1 /* Client interface for General purpose Linux console save/restore server
2 Copyright (C) 1994 Janne Kukonlehto <jtklehto@stekt.oulu.fi>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include <sys/types.h>
28 #include <sys/consio.h>
29 #include <sys/ioctl.h>
30 #endif /* __FreeBSD__ */
34 #include "cons.saver.h"
36 signed char console_flag
= 0;
40 /* The cons saver can't have a pid of 1, used to prevent bunches of
43 int cons_saver_pid
= 1;
44 static int pipefd1
[2] = { -1, -1 };
45 static int pipefd2
[2] = { -1, -1 };
48 show_console_contents_linux (int starty
, unsigned char begin_line
,
49 unsigned char end_line
)
51 unsigned char message
= 0;
52 unsigned short bytes
= 0;
58 /* Paranoid: Is the cons.saver still running? */
59 if (cons_saver_pid
< 1 || kill (cons_saver_pid
, SIGCONT
)) {
65 /* Send command to the console handler */
66 message
= CONSOLE_CONTENTS
;
67 write (pipefd1
[1], &message
, 1);
68 /* Check for outdated cons.saver */
69 read (pipefd2
[0], &message
, 1);
70 if (message
!= CONSOLE_CONTENTS
)
73 /* Send the range of lines that we want */
74 write (pipefd1
[1], &begin_line
, 1);
75 write (pipefd1
[1], &end_line
, 1);
76 /* Read the corresponding number of bytes */
77 read (pipefd2
[0], &bytes
, 2);
79 /* Read the bytes and output them */
80 for (i
= 0; i
< bytes
; i
++) {
82 move (starty
+ (i
/ COLS
), 0);
83 read (pipefd2
[0], &message
, 1);
87 /* Read the value of the console_flag */
88 read (pipefd2
[0], &message
, 1);
92 handle_console_linux (unsigned char action
)
100 /* Close old pipe ends in case it is the 2nd time we run cons.saver */
103 /* Create two pipes for communication */
106 /* Get the console saver running */
107 cons_saver_pid
= fork ();
108 if (cons_saver_pid
< 0) {
116 } else if (cons_saver_pid
> 0) {
118 /* Close the extra pipe ends */
121 /* Was the child successful? */
122 read (pipefd2
[0], &console_flag
, 1);
126 waitpid (cons_saver_pid
, &status
, 0);
130 /* Close the extra pipe ends */
133 tty_name
= ttyname (0);
134 /* Bind the pipe 0 to the standard input */
138 /* Bind the pipe 1 to the standard output */
142 /* Bind standard error to /dev/null */
144 open ("/dev/null", O_WRONLY
);
146 /* Exec the console save/restore handler */
147 mc_conssaver
= concat_dir_and_file (LIBDIR
, "cons.saver");
148 execl (mc_conssaver
, "cons.saver", tty_name
, NULL
);
150 /* Console is not a tty or execl() failed */
152 write (1, &console_flag
, 1);
156 } /* if (cons_saver_pid ...) */
161 case CONSOLE_RESTORE
:
162 /* Is tty console? */
165 /* Paranoid: Is the cons.saver still running? */
166 if (cons_saver_pid
< 1 || kill (cons_saver_pid
, SIGCONT
)) {
171 /* Send command to the console handler */
172 write (pipefd1
[1], &action
, 1);
173 if (action
!= CONSOLE_DONE
) {
174 /* Wait the console handler to do its job */
175 read (pipefd2
[0], &console_flag
, 1);
177 if (action
== CONSOLE_DONE
|| !console_flag
) {
178 /* We are done -> Let's clean up */
181 waitpid (cons_saver_pid
, &status
, 0);
188 #elif defined(__FreeBSD__)
191 * FreeBSD support copyright (C) 2003 Alexander Serkov <serkov@ukrpost.net>.
192 * Support for screenmaps by Max Khon <fjoe@FreeBSD.org>
197 static struct scrshot screen_shot
;
198 static struct vid_info screen_info
;
206 screen_info
.size
= sizeof (screen_info
);
207 if (ioctl (FD_OUT
, CONS_GETINFO
, &screen_info
) == -1)
210 memset (&screen_shot
, 0, sizeof (screen_shot
));
211 screen_shot
.xsize
= screen_info
.mv_csz
;
212 screen_shot
.ysize
= screen_info
.mv_rsz
;
213 if ((screen_shot
.buf
=
214 g_malloc (screen_info
.mv_csz
* screen_info
.mv_rsz
* 2)) == NULL
)
221 set_attr (unsigned attr
)
224 * Convert color indices returned by SCRSHOT (red=4, green=2, blue=1)
225 * to indices for ANSI sequences (red=1, green=2, blue=4).
227 static const int color_map
[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
231 bc
= (attr
>> 4) & 0xF;
233 printf ("\x1B[%d;%d;3%d;4%dm", (bc
& 8) ? 5 : 25, (tc
& 8) ? 1 : 22,
234 color_map
[tc
& 7], color_map
[bc
& 7]);
237 #define cursor_to(x, y) do { \
238 printf("\x1B[%d;%df", (y) + 1, (x) + 1); \
243 console_restore (void)
252 /* restoring all content up to cursor position */
253 last
= screen_info
.mv_row
* screen_info
.mv_csz
+ screen_info
.mv_col
;
254 for (i
= 0; i
< last
; ++i
) {
255 set_attr ((screen_shot
.buf
[i
] >> 8) & 0xFF);
256 putc (screen_shot
.buf
[i
] & 0xFF, stdout
);
259 /* restoring cursor color */
260 set_attr ((screen_shot
.buf
[last
] >> 8) & 0xFF);
266 console_shutdown (void)
271 g_free (screen_shot
.buf
);
286 /* screen_info.size is already set in console_init() */
287 if (ioctl (FD_OUT
, CONS_GETINFO
, &screen_info
) == -1) {
292 /* handle console resize */
293 if (screen_info
.mv_csz
!= screen_shot
.xsize
294 || screen_info
.mv_rsz
!= screen_shot
.ysize
) {
299 if (ioctl (FD_OUT
, CONS_SCRSHOT
, &screen_shot
) == -1) {
304 if (ioctl (FD_OUT
, GIO_SCRNMAP
, &map
) == -1) {
309 for (i
= 0; i
< 256; i
++) {
310 char *p
= memchr (map
.scrmap
, i
, 256);
311 revmap
.scrmap
[i
] = p
? p
- map
.scrmap
: i
;
314 for (i
= 0; i
< screen_shot
.xsize
* screen_shot
.ysize
; i
++) {
316 (screen_shot
.buf
[i
] & 0xff00) | (unsigned char) revmap
.
317 scrmap
[screen_shot
.buf
[i
] & 0xff];
322 show_console_contents_freebsd (int starty
, unsigned char begin_line
,
323 unsigned char end_line
)
331 for (line
= begin_line
; line
<= end_line
; line
++) {
332 move (starty
+ line
- begin_line
, 0);
333 for (col
= 0; col
< min (COLS
, screen_info
.mv_csz
); col
++) {
334 c
= screen_shot
.buf
[line
* screen_info
.mv_csz
+ col
] & 0xFF;
341 handle_console_freebsd (unsigned char action
)
356 case CONSOLE_RESTORE
:
361 #endif /* __FreeBSD__ */
364 show_console_contents (int starty
, unsigned char begin_line
,
365 unsigned char end_line
)
369 if (look_for_rxvt_extensions ()) {
370 show_rxvt_contents (starty
, begin_line
, end_line
);
374 show_console_contents_linux (starty
, begin_line
, end_line
);
375 #elif defined (__FreeBSD__)
376 show_console_contents_freebsd (starty
, begin_line
, end_line
);
383 handle_console (unsigned char action
)
385 if (look_for_rxvt_extensions ())
389 handle_console_linux (action
);
390 #elif defined (__FreeBSD__)
391 handle_console_freebsd (action
);