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