1 /*   */
2 
3 #ifdef BACKGROUND
4 
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <fcntl.h>
8 #include <signal.h>
9 #include <termios.h>
10 #include <string.h>
11 #include <unistd.h>
12 #include <stdarg.h>
13 #include <sys/mman.h>
14 #include <sys/kd.h>
15 #include <sys/ioctl.h>
16 #include <sys/stat.h>
17 #include <sys/vt.h>
18 #include <sys/wait.h>
19 #include <errno.h>
20 #include <ctype.h>
21 #include "vga.h"
22 #include "libvga.h"
23 #include "driver.h"
24 #include "mouse/vgamouse.h"
25 #include "keyboard/vgakeyboard.h"
26 #include "vgabg.h"
27 
28 #define RELEASE 1
29 #define ACQUIRE 2
30 /* #define QUEUE_SIZE 200*/
31 
32 #if 0
33 #define SETSIG(sa, sig, fun) {\
34 	sa.sa_handler = fun; \
35 	sa.sa_flags = 0; \
36 	sa.sa_mask = vt_block_mask; \
37 	sigaction(sig, &sa, NULL); \
38 }
39 #endif
40 
41 #define SETSIG_RE(sa, sig, fun) {\
42 	sa.sa_handler = fun; \
43 	sa.sa_flags = 0; \
44 	sa.sa_mask = __vt_block_mask_release; \
45 	sigaction(sig, &sa, NULL); \
46 }
47 
48 #define SETSIG_AQ(sa, sig, fun) {\
49 	sa.sa_handler = fun; \
50 	sa.sa_flags = 0; \
51 	sa.sa_mask = __vt_block_mask_aquire; \
52 	sigaction(sig, &sa, NULL); \
53 }
54 
55 
56 /*#define DEBUG  */
57 
58 /* Virtual console switching */
59 
60 static int release_acquire=0;
61 
62 static int forbidvtrelease = 0;
63 static int forbidvtacquire = 0;
64 static int lock_count = 0;
65 static int release_flag = 0;
66 
67 static int __vt_switching_not_ok = 0;
68 static int __vt_switching_asked = 0;
69 static int __vt_check_last_signal = 0;	/* Never the same signal twice */
70 static sigset_t __vt_block_mask_aquire;
71 static sigset_t __vt_block_mask_release;
72 static sigset_t __vt_block_mask_switching;
73 
74 #if 0
75 static sigset_t vt_block_mask;
76 
77 unsigned char *__svga_graph_mem_orginal;
78 unsigned char *__svga_graph_mem_check;
79 
80 static int __svgalib_oktowrite = 1;
81 /* __svgalib_oktowrite tells if it is safe to write registers. */
82 
83 static int __svgalib_virtual_mem_fd = -1;
84 static int __svga_processnumber = -1;
85 #endif
86 
87 static int __vt_switching_state=RELEASE;
88 static int __vt_switching_signal_no;
89 /*
90 static int __vt_switching_to_queue[QUEUE_SIZE] = {0};
91 static int __vt_switching_signal_no_queue[QUEUE_SIZE] = {0};
92 static int __vt_signalqueuepointer = 0;
93 static int __vt_signalqueuenewpointer = 0;
94 */
95 
96 /* User defined functions for vc switching. */
97 void (*__svgalib_go_to_background) (void) = 0;
98 void (*__svgalib_come_from_background) (void) = 0;
99 
100 
101 #endif
102 
103 #ifdef BACKGROUND
104 
105 static void releasevt_signal(int n);
106 static void acquirevt_signal(int n);
107 
__releasevt_signal(int n)108 static void __releasevt_signal(int n)
109 {
110 /*    struct sigaction siga; */
111 
112 
113     if (lock_count) {
114 	release_flag = 1;
115 	return;
116     }
117 #ifdef DEBUG
118     printf("Release request.\n");
119 #endif
120 
121     forbidvtacquire = 1;
122     /*SETSIG(siga, SVGALIB_RELEASE_SIG, releasevt_signal); */
123 
124     if (forbidvtrelease) {
125 	forbidvtacquire = 0;
126 	ioctl(__svgalib_tty_fd, VT_RELDISP, 0);
127 	return;
128     }
129     if (__svgalib_go_to_background)
130 	(__svgalib_go_to_background) ();
131 
132     __vt_check_last_signal = RELEASE;
133     __vt_switching_state=RELEASE;
134     __svgalib_flipaway();
135     ioctl(__svgalib_tty_fd, VT_RELDISP, 1);
136 #ifdef DEBUG
137     printf("Finished release.\n");
138 #endif
139     forbidvtacquire = 0;
140         if((__svgalib_textprog&3)==3){
141            pid_t child;
142            if((child=fork())==0){
143            execv(__svgalib_TextProg,__svgalib_TextProg_argv);
144            } else {
145            waitpid(child,NULL,0);
146            };
147         };
148 
149     /* Suspend program until switched to again. */
150 #ifdef DEBUG
151     printf("Suspended.\n");
152 #endif
153     __svgalib_oktowrite = 0;
154     if (!__svgalib_runinbackground)
155 	__svgalib_waitvtactive();
156 #ifdef DEBUG
157     printf("Waked.\n");
158 #endif
159 }
160 
releasevt_signal(int n)161 static void releasevt_signal(int n)
162 {
163     struct sigaction siga;
164 
165 #ifdef DEBUG
166     printf("vt: rel ");
167 #endif
168     if (__vt_switching_not_ok || __vt_switching_asked) {
169 	if (__vt_check_last_signal != RELEASE)
170 	    {
171 	     __vt_switching_asked=1;
172 	     __vt_switching_signal_no=n;
173 	     __vt_switching_state=RELEASE;
174 	    }
175     } else {
176 	/* __svgalib_dont_switch_vt_yet(); */
177 	if (__vt_check_last_signal != RELEASE)
178 	    __releasevt_signal(n);	/* sets __vt_check_last_signal */
179 	/* __svgalib_is_vt_switching_needed(); */
180     }
181     SETSIG_AQ(siga, SVGALIB_ACQUIRE_SIG, acquirevt_signal);
182     SETSIG_RE(siga, SVGALIB_RELEASE_SIG, releasevt_signal);
183 #ifdef DEBUG
184     printf("ok\n");
185 #endif
186     return;
187 }
188 
__acquirevt_signal(int n)189 static void __acquirevt_signal(int n)
190 {
191 /*    struct sigaction siga; */
192 #ifdef DEBUG
193     printf("Acquisition request.\n");
194 #endif
195     /* vt_check_last_signal=ACQUIRE; */
196     forbidvtrelease = 1;
197     /*SETSIG(siga, SVGALIB_ACQUIRE_SIG, acquirevt_signal); */
198     if (forbidvtacquire) {
199 	forbidvtrelease = 0;
200 	return;
201     }
202     __vt_check_last_signal = ACQUIRE;
203     __vt_switching_state=ACQUIRE;
204     __svgalib_flipback();
205     ioctl(__svgalib_tty_fd, VT_RELDISP, VT_ACKACQ);
206 #ifdef DEBUG
207     printf("Finished acquisition.\n");
208 #endif
209     /*forbidvtrelease = 0; */
210     __svgalib_oktowrite = 1;
211     if (__svgalib_come_from_background)
212 	(__svgalib_come_from_background) ();
213     forbidvtrelease = 0;
214 }
215 
acquirevt_signal(int n)216 static void acquirevt_signal(int n)
217 {
218     struct sigaction siga;
219 
220 #ifdef DEBUG
221     printf("vt: acq ");
222 #endif
223     if (__vt_switching_not_ok || __vt_switching_asked) {
224 	if (__vt_check_last_signal != ACQUIRE)
225 	    {
226 	     __vt_switching_asked=1;
227 	     __vt_switching_signal_no=n;
228              __vt_switching_state=ACQUIRE;
229 	    }
230     } else {
231 	/* __svgalib_dont_switch_vt_yet(); */
232 	if (__vt_check_last_signal != ACQUIRE)
233 	    __acquirevt_signal(n);	/* sets __vt_check_last_signal */
234 	/* __svgalib_is_vt_switching_needed(); */
235     }
236     SETSIG_RE(siga, SVGALIB_RELEASE_SIG, releasevt_signal);
237     SETSIG_AQ(siga, SVGALIB_ACQUIRE_SIG, acquirevt_signal);
238 #ifdef DEBUG
239     printf("ok\n");
240 #endif
241     return;
242 }
243 
__svgalib_dont_switch_vt_yet(void)244 void __svgalib_dont_switch_vt_yet(void)
245 {
246     __vt_switching_not_ok++;
247     return;
248 }
249 
__svgalib_is_vt_switching_needed(void)250 void __svgalib_is_vt_switching_needed(void)
251 {
252 
253     __vt_switching_not_ok--;
254     if (__vt_switching_not_ok < 0) {
255 	__vt_switching_not_ok = 0;
256 	printf("svgalib: lock warning, over done.\n");
257     }
258 
259     if (__vt_switching_not_ok) return;
260 
261     if (__vt_switching_asked)
262         {
263          /* Block signals... hmm ignore them */
264          sigprocmask(SIG_BLOCK,&__vt_block_mask_switching,NULL);
265 	 if (__vt_switching_state==RELEASE &&
266 	     __vt_check_last_signal!=RELEASE) {
267 #ifdef DEBUG
268 	     printf("RELEASE ");
269 #endif
270 	     __releasevt_signal(__vt_switching_signal_no);
271 	     __vt_switching_signal_no=0;
272              __vt_switching_state=ACQUIRE;
273 #ifdef DEBUG
274 	     printf("OK.\n");
275 #endif
276 	 }
277 	  else
278 	  {
279 	   if (__vt_switching_state==ACQUIRE &&
280 	       __vt_check_last_signal!=ACQUIRE) {
281 #ifdef DEBUG
282 	       printf("ACQUIRE ");
283 #endif
284 	       __acquirevt_signal(__vt_switching_signal_no);
285 	       __vt_switching_signal_no=0;
286                __vt_switching_state=RELEASE;
287 #ifdef DEBUG
288 	       printf("OK.\n");
289 #endif
290 	    }
291 	   }
292 
293 	 __vt_switching_asked=0;
294          sigprocmask(SIG_UNBLOCK,&__vt_block_mask_switching,NULL);
295         }
296     return;
297 }
298 
299 /* These both variables should be static. However, oldvtmode is
300    restored in vga.c.. so.. */
301 
302 struct vt_mode __svgalib_oldvtmode;
303 static struct vt_mode newvtmode;
304 
__svgalib_takevtcontrol(void)305 void __svgalib_takevtcontrol(void)
306 {
307     struct sigaction siga;
308 
309     ioctl(__svgalib_tty_fd, VT_GETMODE, &__svgalib_oldvtmode);
310     newvtmode = __svgalib_oldvtmode;
311     newvtmode.mode = VT_PROCESS;	/* handle VT changes */
312     newvtmode.relsig = SVGALIB_RELEASE_SIG;	/* I didn't find SIGUSR1/2 anywhere */
313     newvtmode.acqsig = SVGALIB_ACQUIRE_SIG;	/* in the kernel sources, so I guess */
314                                         /* they are free */
315 
316 
317     sigemptyset(&__vt_block_mask_switching);
318     sigaddset(&__vt_block_mask_switching,SVGALIB_RELEASE_SIG|SVGALIB_ACQUIRE_SIG);
319 
320     sigemptyset(&__vt_block_mask_aquire);
321     sigaddset(&__vt_block_mask_aquire, SVGALIB_RELEASE_SIG);
322     sigemptyset(&__vt_block_mask_release);
323     sigaddset(&__vt_block_mask_release, SVGALIB_ACQUIRE_SIG);
324     SETSIG_RE(siga, SVGALIB_RELEASE_SIG, releasevt_signal);
325     SETSIG_AQ(siga, SVGALIB_ACQUIRE_SIG, acquirevt_signal);
326     ioctl(__svgalib_tty_fd, VT_SETMODE, &newvtmode);
327     return;
328 }
329 
vga_lockvc(void)330 void vga_lockvc(void)
331 {
332     lock_count++;
333     if (__svgalib_flip_status())
334 	__svgalib_waitvtactive();
335     return;
336 }
337 
vga_unlockvc(void)338 void vga_unlockvc(void)
339 {
340     if (--lock_count <= 0) {
341 	lock_count = 0;
342 	if (release_flag) {
343 	    release_flag = 0;
344 	    releasevt_signal(SVGALIB_RELEASE_SIG);
345 	}
346     }
347     return;
348 }
349 
vga_runinbackground(int stat,...)350 void vga_runinbackground(int stat,...)
351 {
352     va_list params;
353 
354     va_start(params, stat);
355     switch (stat) {
356     case VGA_GOTOBACK:
357 	__svgalib_go_to_background = va_arg(params, void *);
358 	break;
359     case VGA_COMEFROMBACK:
360 	__svgalib_come_from_background = va_arg(params, void *);
361 	break;
362     default:
363 	__svgalib_runinbackground = stat;
364 	break;
365     }
366     va_end(params);
367 }
368 
369 #endif
370