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. */
18 /* The cons saver can't have a pid of 1, used to prevent bunches of */
25 #include <sys/types.h>
30 #include "cons.saver.h"
32 signed char console_flag
= 0;
34 #if defined(linux) || defined(__linux__)
37 int cons_saver_pid
= 1;
38 static int pipefd1
[2] = {-1, -1}, pipefd2
[2] = {-1, -1};
40 void show_console_contents (int starty
, unsigned char begin_line
, unsigned char end_line
)
42 unsigned char message
= 0;
43 unsigned short bytes
= 0;
48 if (look_for_rxvt_extensions ()) {
49 show_rxvt_contents (starty
, begin_line
, end_line
);
56 /* Paranoid: Is the cons.saver still running? */
57 if (cons_saver_pid
< 1 || kill (cons_saver_pid
, SIGCONT
)){
63 /* Send command to the console handler */
64 message
= CONSOLE_CONTENTS
;
65 write (pipefd1
[1], &message
, 1);
66 /* Check for outdated cons.saver */
67 read (pipefd2
[0], &message
, 1);
68 if (message
!= CONSOLE_CONTENTS
)
71 /* Send the range of lines that we want */
72 write (pipefd1
[1], &begin_line
, 1);
73 write (pipefd1
[1], &end_line
, 1);
74 /* Read the corresponding number of bytes */
75 read (pipefd2
[0], &bytes
, 2);
77 /* Read the bytes and output them */
78 for (i
= 0; i
< bytes
; i
++){
80 move (starty
+(i
/COLS
), 0);
81 read (pipefd2
[0], &message
, 1);
85 /* Read the value of the console_flag */
86 read (pipefd2
[0], &message
, 1);
89 void handle_console (unsigned char action
)
97 if (look_for_rxvt_extensions ())
99 /* Close old pipe ends in case it is the 2nd time we run cons.saver */
102 /* Create two pipes for communication */
105 /* Get the console saver running */
106 cons_saver_pid
= fork ();
107 if (cons_saver_pid
< 0){
115 } else if (cons_saver_pid
> 0){
117 /* Close the extra pipe ends */
120 /* Was the child successful? */
121 read (pipefd2
[0], &console_flag
, 1);
125 waitpid (cons_saver_pid
, &status
, 0);
129 /* Close the extra pipe ends */
132 tty_name
= ttyname (0);
133 /* Bind the pipe 0 to the standard input */
137 /* Bind the pipe 1 to the standard output */
141 /* Bind standard error to /dev/null */
143 open ("/dev/null", O_WRONLY
);
145 /* Exec the console save/restore handler */
146 mc_conssaver
= concat_dir_and_file (LIBDIR
, "cons.saver");
147 execl (mc_conssaver
, "cons.saver", tty_name
, NULL
);
149 /* Console is not a tty or execl() failed */
151 write (1, &console_flag
, 1);
155 } /* if (cons_saver_pid ...) */
160 case CONSOLE_RESTORE
:
161 if (look_for_rxvt_extensions ())
163 /* Is tty console? */
166 /* Paranoid: Is the cons.saver still running? */
167 if (cons_saver_pid
< 1 || kill (cons_saver_pid
, SIGCONT
)){
172 /* Send command to the console handler */
173 write (pipefd1
[1], &action
, 1);
174 if (action
!= CONSOLE_DONE
){
175 /* Wait the console handler to do its job */
176 read (pipefd2
[0], &console_flag
, 1);
178 if (action
== CONSOLE_DONE
|| !console_flag
){
179 /* We are done -> Let's clean up */
182 waitpid (cons_saver_pid
, &status
, 0);
189 #endif /* #ifdef linux */
193 ** SCO console save/restore handling routines
194 ** Copyright (C) 1997 Alex Tkachenko <alex@bcs.zaporizhzhe.ua>
198 #include <sys/types.h>
200 #include <sys/console.h>
201 #include <sys/vtkd.h>
207 #include "cons.saver.h"
209 static int FD_OUT
= 2;
211 static unsigned short* vidbuf
= NULL
;
212 static unsigned short* screen
= NULL
;
213 static int height
= 0, width
= 0, saved_attr
= 0;
216 #define SIG_ACQUIRE 21 /* originally: handset, line status change (?) */
222 int adapter
= ioctl(FD_OUT
, CONS_CURRENT
, 0);
224 vi
.size
= sizeof(struct vid_info
);
225 ioctl(FD_OUT
, CONS_GETINFO
, &(vi
));
226 return (vi
.m_num
== ioctl(FD_OUT
,CONSADP
,adapter
));
232 struct vt_mode smode
;
234 signal(SIG_ACQUIRE
, SIG_DFL
);
235 smode
.mode
= VT_AUTO
;
236 smode
.waitv
= smode
.relsig
= smode
.acqsig
= smode
.frsig
= 0;
237 ioctl(FD_OUT
, VT_SETMODE
, &smode
);
238 ioctl(FD_OUT
, VT_RELDISP
, VT_ACKACQ
);
258 struct m6845_info mi
;
267 struct vt_mode smode
;
270 ** User switched out of our vt. Let's wait until we get SIG_ACQUIRE,
271 ** otherwise we could save wrong screen image
273 signal(SIG_ACQUIRE
, console_acquire_vt
);
274 smode
.mode
= VT_PROCESS
;
276 smode
.waitv
= smode
.relsig
= smode
.acqsig
= smode
.frsig
= SIG_ACQUIRE
;
277 ioctl(FD_OUT
, VT_SETMODE
, &smode
);
282 saved_attr
= ioctl(FD_OUT
, GIO_ATTR
, 0);
284 vidbuf
= (unsigned short*) ioctl(FD_OUT
, MAPCONS
, 0);
286 mi
.size
= sizeof(struct m6845_info
);
287 ioctl(FD_OUT
, CONS_6845INFO
, &mi
);
290 unsigned short* start
= vidbuf
+ mi
.screen_top
;
291 memcpy(screen
, start
, width
* height
* 2);
294 write(FD_OUT
,"\0337",2); /* save cursor position */
300 struct m6845_info mi
;
301 unsigned short* start
;
308 write (FD_OUT
, "\033[2J", 4);
310 mi
.size
= sizeof(struct m6845_info
);
311 ioctl(FD_OUT
, CONS_6845INFO
, &mi
);
313 start
= vidbuf
+ mi
.screen_top
;
314 memcpy(start
, screen
, width
* height
* 2);
315 write(FD_OUT
,"\0338",2); /* restore cursor position */
322 int adapter
= ioctl(FD_OUT
, CONS_CURRENT
, 0);
328 vi
.size
= sizeof(struct vid_info
);
329 ioctl(FD_OUT
, CONS_GETINFO
, &(vi
));
338 screen
= (unsigned short*) g_malloc (height
* width
* 2);
345 mode
= ioctl(FD_OUT
, CONS_GET
, 0);
346 ioctl(FD_OUT
, MODESWITCH
| mode
, 0);
353 handle_console (unsigned char action
)
355 if (look_for_rxvt_extensions ())
370 case CONSOLE_RESTORE
:
379 show_console_contents (int starty
, unsigned char begin_line
, unsigned char end_line
)
381 register int i
, len
= (end_line
- begin_line
) * width
;
383 if (look_for_rxvt_extensions ()) {
384 show_rxvt_contents (starty
, begin_line
, end_line
);
387 attrset(DEFAULT_COLOR
);
388 for (i
= 0; i
< len
; i
++)
390 if ((i
% width
) == 0)
391 move (starty
+(i
/width
), 0);
392 addch ((unsigned char)screen
[width
*starty
+ i
]);
396 #endif /* SCO_FLAVOR */
399 #if !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR)
403 void show_console_contents (int starty
, unsigned char begin_line
, unsigned char end_line
)
407 if (look_for_rxvt_extensions ()) {
408 show_rxvt_contents (starty
, begin_line
, end_line
);
414 void handle_console (unsigned char action
)
416 look_for_rxvt_extensions ();
419 #endif /* !defined(linux) && !defined(__linux__) && !defined(SCO_FLAVOR) */