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