This source file includes following definitions.
- show_console_contents_linux
- handle_console_linux
- console_init
- set_attr
- console_restore
- console_shutdown
- console_save
- show_console_contents_freebsd
- handle_console_freebsd
- show_console_contents
- handle_console
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include <config.h>
28
29 #include <stdlib.h>
30 #include <sys/wait.h>
31 #include <signal.h>
32 #include <stdio.h>
33 #include <sys/types.h>
34 #ifdef __FreeBSD__
35 #include <sys/consio.h>
36 #ifdef HAVE_SYS_IOCTL_H
37 #include <sys/ioctl.h>
38 #endif
39 #endif
40
41 #include "lib/global.h"
42
43 #include "lib/unixcompat.h"
44 #include "lib/tty/tty.h"
45 #include "lib/tty/color.h"
46 #include "lib/tty/win.h"
47 #include "lib/util.h"
48
49 #include "consaver/cons.saver.h"
50
51
52
53 #ifdef __linux__
54 int cons_saver_pid = 1;
55 #endif
56
57
58
59 #if defined(__FreeBSD__)
60 #define FD_OUT 1
61 #define cursor_to(x, y) \
62 do \
63 { \
64 printf("\x1B[%d;%df", (y) + 1, (x) + 1); \
65 fflush(stdout); \
66 } while (0)
67 #endif
68
69
70
71
72
73
74
75 #ifdef __linux__
76
77
78 static int pipefd1[2] = { -1, -1 };
79 static int pipefd2[2] = { -1, -1 };
80 #elif defined(__FreeBSD__)
81 static struct scrshot screen_shot;
82 static struct vid_info screen_info;
83 #endif
84
85
86
87
88
89 #ifdef __linux__
90 static void
91 show_console_contents_linux (int starty, unsigned char begin_line, unsigned char end_line)
92 {
93 unsigned char message = 0;
94 unsigned short bytes = 0;
95 int i;
96 ssize_t ret;
97
98
99 if (mc_global.tty.console_flag == '\0')
100 return;
101
102 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT))
103 {
104 cons_saver_pid = 0;
105 mc_global.tty.console_flag = '\0';
106 return;
107 }
108
109
110 message = CONSOLE_CONTENTS;
111 ret = write (pipefd1[1], &message, 1);
112
113 ret = read (pipefd2[0], &message, 1);
114 if (message != CONSOLE_CONTENTS)
115 return;
116
117
118 ret = write (pipefd1[1], &begin_line, 1);
119 ret = write (pipefd1[1], &end_line, 1);
120
121 ret = read (pipefd2[0], &bytes, 2);
122
123
124 for (i = 0; i < bytes; i++)
125 {
126 if ((i % COLS) == 0)
127 tty_gotoyx (starty + (i / COLS), 0);
128 ret = read (pipefd2[0], &message, 1);
129 tty_print_char (message);
130 }
131
132
133 ret = read (pipefd2[0], &message, 1);
134 (void) ret;
135 }
136
137
138
139 static void
140 handle_console_linux (console_action_t action)
141 {
142 int status;
143
144 switch (action)
145 {
146 case CONSOLE_INIT:
147
148 status = close (pipefd1[1]);
149 status = close (pipefd2[0]);
150
151 if (!((pipe (pipefd1) == 0) && ((pipe (pipefd2)) == 0)))
152 {
153 mc_global.tty.console_flag = '\0';
154 break;
155 }
156
157 cons_saver_pid = my_fork ();
158 if (cons_saver_pid < 0)
159 {
160
161
162 status = close (pipefd1[1]);
163 status = close (pipefd1[0]);
164 status = close (pipefd2[1]);
165 status = close (pipefd2[0]);
166 mc_global.tty.console_flag = '\0';
167 }
168 else if (cons_saver_pid > 0)
169 {
170
171
172 status = close (pipefd1[0]);
173 status = close (pipefd2[1]);
174
175 status = read (pipefd2[0], &mc_global.tty.console_flag, 1);
176 if (mc_global.tty.console_flag == '\0')
177 {
178 pid_t ret;
179 status = close (pipefd1[1]);
180 status = close (pipefd2[0]);
181 ret = waitpid (cons_saver_pid, &status, 0);
182 (void) ret;
183 }
184 }
185 else
186 {
187
188 char *tty_name;
189
190
191 status = close (pipefd1[1]);
192 status = close (pipefd2[0]);
193 tty_name = ttyname (0);
194
195 do
196 {
197 gboolean ok;
198
199 if (dup2 (pipefd1[0], STDIN_FILENO) == -1)
200 break;
201 status = close (pipefd1[0]);
202
203 if (dup2 (pipefd2[1], STDOUT_FILENO) == -1)
204 break;
205
206 status = close (pipefd2[1]);
207
208 status = open ("/dev/null", O_WRONLY);
209 if (status == -1)
210 break;
211 ok = dup2 (status, STDERR_FILENO) != -1;
212 status = close (status);
213 if (!ok)
214 break;
215
216 if (tty_name != NULL)
217 {
218 char *mc_conssaver;
219
220
221 mc_conssaver = mc_build_filename (SAVERDIR, "cons.saver", (char *) NULL);
222 execl (mc_conssaver, "cons.saver", tty_name, (char *) NULL);
223 }
224
225 }
226 while (0);
227 mc_global.tty.console_flag = '\0';
228 status = write (1, &mc_global.tty.console_flag, 1);
229 my_exit (3);
230 }
231 break;
232
233 case CONSOLE_DONE:
234 case CONSOLE_SAVE:
235 case CONSOLE_RESTORE:
236
237 if (mc_global.tty.console_flag == '\0')
238 return;
239
240 if (cons_saver_pid < 1 || kill (cons_saver_pid, SIGCONT))
241 {
242 cons_saver_pid = 0;
243 mc_global.tty.console_flag = '\0';
244 return;
245 }
246
247 {
248
249
250 char act = (char) action;
251
252 status = write (pipefd1[1], &act, 1);
253 }
254 if (action != CONSOLE_DONE)
255 {
256
257 status = read (pipefd2[0], &mc_global.tty.console_flag, 1);
258 }
259 if (action == CONSOLE_DONE || mc_global.tty.console_flag == '\0')
260 {
261
262 pid_t ret;
263 close (pipefd1[1]);
264 close (pipefd2[0]);
265 ret = waitpid (cons_saver_pid, &status, 0);
266 (void) ret;
267 mc_global.tty.console_flag = '\0';
268 }
269 break;
270 default:
271 break;
272 }
273 }
274
275 #elif defined(__FreeBSD__)
276
277
278
279
280
281
282
283 static void
284 console_init (void)
285 {
286 if (mc_global.tty.console_flag != '\0')
287 return;
288
289 screen_info.size = sizeof (screen_info);
290 if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1)
291 return;
292
293 memset (&screen_shot, 0, sizeof (screen_shot));
294 screen_shot.xsize = screen_info.mv_csz;
295 screen_shot.ysize = screen_info.mv_rsz;
296 screen_shot.buf = g_try_malloc (screen_info.mv_csz * screen_info.mv_rsz * 2);
297 if (screen_shot.buf != NULL)
298 mc_global.tty.console_flag = '\001';
299 }
300
301
302
303 static void
304 set_attr (unsigned attr)
305 {
306
307
308
309
310 static const int color_map[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
311 int bc, tc;
312
313 tc = attr & 0xF;
314 bc = (attr >> 4) & 0xF;
315
316 printf ("\x1B[%d;%d;3%d;4%dm", (bc & 8) ? 5 : 25, (tc & 8) ? 1 : 22,
317 color_map[tc & 7], color_map[bc & 7]);
318 }
319
320
321
322 static void
323 console_restore (void)
324 {
325 int i, last;
326
327 if (mc_global.tty.console_flag == '\0')
328 return;
329
330 cursor_to (0, 0);
331
332
333 last = screen_info.mv_row * screen_info.mv_csz + screen_info.mv_col;
334 for (i = 0; i < last; ++i)
335 {
336 set_attr ((screen_shot.buf[i] >> 8) & 0xFF);
337 putc (screen_shot.buf[i] & 0xFF, stdout);
338 }
339
340
341 set_attr ((screen_shot.buf[last] >> 8) & 0xFF);
342
343 fflush (stdout);
344 }
345
346
347
348 static void
349 console_shutdown (void)
350 {
351 if (mc_global.tty.console_flag == '\0')
352 return;
353
354 g_free (screen_shot.buf);
355
356 mc_global.tty.console_flag = '\0';
357 }
358
359
360
361 static void
362 console_save (void)
363 {
364 int i;
365 scrmap_t map;
366 scrmap_t revmap;
367
368 if (mc_global.tty.console_flag == '\0')
369 return;
370
371
372 if (ioctl (FD_OUT, CONS_GETINFO, &screen_info) == -1)
373 {
374 console_shutdown ();
375 return;
376 }
377
378
379 if (screen_info.mv_csz != screen_shot.xsize || screen_info.mv_rsz != screen_shot.ysize)
380 {
381 console_shutdown ();
382 console_init ();
383 }
384
385 if (ioctl (FD_OUT, CONS_SCRSHOT, &screen_shot) == -1)
386 {
387 console_shutdown ();
388 return;
389 }
390
391 if (ioctl (FD_OUT, GIO_SCRNMAP, &map) == -1)
392 {
393 console_shutdown ();
394 return;
395 }
396
397 for (i = 0; i < 256; i++)
398 {
399 char *p = memchr (map.scrmap, i, 256);
400 revmap.scrmap[i] = p ? p - map.scrmap : i;
401 }
402
403 for (i = 0; i < screen_shot.xsize * screen_shot.ysize; i++)
404 {
405
406 screen_shot.buf[i] = (screen_shot.buf[i] & 0xff00)
407 | (unsigned char) revmap.scrmap[screen_shot.buf[i] & 0xff];
408
409 }
410 }
411
412
413
414 static void
415 show_console_contents_freebsd (int starty, unsigned char begin_line, unsigned char end_line)
416 {
417 int col, line;
418 char c;
419
420 if (mc_global.tty.console_flag == '\0')
421 return;
422
423 for (line = begin_line; line <= end_line; line++)
424 {
425 tty_gotoyx (starty + line - begin_line, 0);
426 for (col = 0; col < MIN (COLS, screen_info.mv_csz); col++)
427 {
428 c = screen_shot.buf[line * screen_info.mv_csz + col] & 0xFF;
429 tty_print_char (c);
430 }
431 }
432 }
433
434
435
436 static void
437 handle_console_freebsd (console_action_t action)
438 {
439 switch (action)
440 {
441 case CONSOLE_INIT:
442 console_init ();
443 break;
444
445 case CONSOLE_DONE:
446 console_shutdown ();
447 break;
448
449 case CONSOLE_SAVE:
450 console_save ();
451 break;
452
453 case CONSOLE_RESTORE:
454 console_restore ();
455 break;
456 default:
457 break;
458 }
459 }
460 #endif
461
462
463
464
465
466 void
467 show_console_contents (int starty, unsigned char begin_line, unsigned char end_line)
468 {
469 tty_set_normal_attrs ();
470
471 if (look_for_rxvt_extensions ())
472 {
473 show_rxvt_contents (starty, begin_line, end_line);
474 return;
475 }
476 #ifdef __linux__
477 show_console_contents_linux (starty, begin_line, end_line);
478 #elif defined (__FreeBSD__)
479 show_console_contents_freebsd (starty, begin_line, end_line);
480 #else
481 mc_global.tty.console_flag = '\0';
482 #endif
483 }
484
485
486
487 void
488 handle_console (console_action_t action)
489 {
490 (void) action;
491
492 if (look_for_rxvt_extensions ())
493 return;
494
495 #ifdef __linux__
496 handle_console_linux (action);
497 #elif defined (__FreeBSD__)
498 handle_console_freebsd (action);
499 #endif
500 }
501
502