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