Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Thomas Roell not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Thomas Roell makes no representations | |
11 | * about the suitability of this software for any purpose. It is provided | |
12 | * "as is" without express or implied warranty. | |
13 | * | |
14 | * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | * | |
22 | */ | |
23 | /* | |
24 | * Copyright (c) 1994-2003 by The XFree86 Project, Inc. | |
25 | * | |
26 | * Permission is hereby granted, free of charge, to any person obtaining a | |
27 | * copy of this software and associated documentation files (the "Software"), | |
28 | * to deal in the Software without restriction, including without limitation | |
29 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
30 | * and/or sell copies of the Software, and to permit persons to whom the | |
31 | * Software is furnished to do so, subject to the following conditions: | |
32 | * | |
33 | * The above copyright notice and this permission notice shall be included in | |
34 | * all copies or substantial portions of the Software. | |
35 | * | |
36 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
37 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
38 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
39 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
40 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
41 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
42 | * OTHER DEALINGS IN THE SOFTWARE. | |
43 | * | |
44 | * Except as contained in this notice, the name of the copyright holder(s) | |
45 | * and author(s) shall not be used in advertising or otherwise to promote | |
46 | * the sale, use or other dealings in this Software without prior written | |
47 | * authorization from the copyright holder(s) and author(s). | |
48 | */ | |
49 | ||
50 | /* [JCH-96/01/21] Extended std reverse map to four buttons. */ | |
51 | ||
52 | #ifdef HAVE_XORG_CONFIG_H | |
53 | #include <xorg-config.h> | |
54 | #endif | |
55 | ||
56 | #include <X11/X.h> | |
57 | #include <X11/Xpoll.h> | |
58 | #include <X11/Xproto.h> | |
59 | #include "misc.h" | |
60 | #include "compiler.h" | |
61 | #include "xf86.h" | |
62 | #include "xf86Priv.h" | |
63 | #define XF86_OS_PRIVS | |
64 | #include "xf86_OSlib.h" | |
65 | #include <X11/keysym.h> | |
66 | ||
67 | #ifdef XFreeXDGA | |
68 | #include "dgaproc.h" | |
69 | #endif | |
70 | ||
71 | #include <X11/extensions/XI.h> | |
72 | #include <X11/extensions/XIproto.h> | |
73 | #include "inputstr.h" | |
74 | #include "xf86Xinput.h" | |
75 | ||
76 | #include "mi.h" | |
77 | #include "mipointer.h" | |
78 | ||
79 | #include "xkbsrv.h" | |
80 | #include "xkbstr.h" | |
81 | ||
82 | #ifdef DPMSExtension | |
83 | #include <X11/extensions/dpmsconst.h> | |
84 | #include "dpmsproc.h" | |
85 | #endif | |
86 | ||
87 | #include "xf86platformBus.h" | |
88 | /* | |
89 | * This is a toggling variable: | |
90 | * FALSE = No VT switching keys have been pressed last time around | |
91 | * TRUE = Possible VT switch Pending | |
92 | * (DWH - 12/2/93) | |
93 | * | |
94 | * This has been generalised to work with Linux and *BSD+syscons (DHD) | |
95 | */ | |
96 | ||
97 | Bool VTSwitchEnabled = TRUE; /* Allows run-time disabling for | |
98 | *BSD and for avoiding VT | |
99 | switches when using the DRI | |
100 | automatic full screen mode.*/ | |
101 | ||
102 | extern fd_set EnabledDevices; | |
103 | ||
104 | #ifdef XF86PM | |
105 | extern void (*xf86OSPMClose) (void); | |
106 | #endif | |
107 | ||
108 | static void xf86VTSwitch(void); | |
109 | ||
110 | /* | |
111 | * Allow arbitrary drivers or other XFree86 code to register with our main | |
112 | * Wakeup handler. | |
113 | */ | |
114 | typedef struct x_IHRec { | |
115 | int fd; | |
116 | InputHandlerProc ihproc; | |
117 | pointer data; | |
118 | Bool enabled; | |
119 | Bool is_input; | |
120 | struct x_IHRec *next; | |
121 | } IHRec, *IHPtr; | |
122 | ||
123 | static IHPtr InputHandlers = NULL; | |
124 | ||
125 | Bool | |
126 | LegalModifier(unsigned int key, DeviceIntPtr pDev) | |
127 | { | |
128 | return TRUE; | |
129 | } | |
130 | ||
131 | /* | |
132 | * TimeSinceLastInputEvent -- | |
133 | * Function used for screensaver purposes by the os module. Returns the | |
134 | * time in milliseconds since there last was any input. | |
135 | */ | |
136 | int | |
137 | TimeSinceLastInputEvent(void) | |
138 | { | |
139 | if (xf86Info.lastEventTime == 0) { | |
140 | xf86Info.lastEventTime = GetTimeInMillis(); | |
141 | } | |
142 | return GetTimeInMillis() - xf86Info.lastEventTime; | |
143 | } | |
144 | ||
145 | /* | |
146 | * SetTimeSinceLastInputEvent -- | |
147 | * Set the lastEventTime to now. | |
148 | */ | |
149 | void | |
150 | SetTimeSinceLastInputEvent(void) | |
151 | { | |
152 | xf86Info.lastEventTime = GetTimeInMillis(); | |
153 | } | |
154 | ||
155 | /* | |
156 | * ProcessInputEvents -- | |
157 | * Retrieve all waiting input events and pass them to DIX in their | |
158 | * correct chronological order. Only reads from the system pointer | |
159 | * and keyboard. | |
160 | */ | |
161 | void | |
162 | ProcessInputEvents(void) | |
163 | { | |
164 | int x, y; | |
165 | ||
166 | mieqProcessInputEvents(); | |
167 | ||
168 | /* FIXME: This is a problem if we have multiple pointers */ | |
169 | miPointerGetPosition(inputInfo.pointer, &x, &y); | |
170 | ||
171 | xf86SetViewport(xf86Info.currentScreen, x, y); | |
172 | } | |
173 | ||
174 | /* | |
175 | * Handle keyboard events that cause some kind of "action" | |
176 | * (i.e., server termination, video mode changes, VT switches, etc.) | |
177 | */ | |
178 | void | |
179 | xf86ProcessActionEvent(ActionEvent action, void *arg) | |
180 | { | |
181 | DebugF("ProcessActionEvent(%d,%x)\n", (int) action, arg); | |
182 | switch (action) { | |
183 | case ACTION_TERMINATE: | |
184 | if (!xf86Info.dontZap) { | |
185 | xf86Msg(X_INFO, "Server zapped. Shutting down.\n"); | |
186 | #ifdef XFreeXDGA | |
187 | DGAShutdown(); | |
188 | #endif | |
189 | GiveUp(0); | |
190 | } | |
191 | break; | |
192 | case ACTION_NEXT_MODE: | |
193 | if (!xf86Info.dontZoom) | |
194 | xf86ZoomViewport(xf86Info.currentScreen, 1); | |
195 | break; | |
196 | case ACTION_PREV_MODE: | |
197 | if (!xf86Info.dontZoom) | |
198 | xf86ZoomViewport(xf86Info.currentScreen, -1); | |
199 | break; | |
200 | case ACTION_SWITCHSCREEN: | |
201 | if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) { | |
202 | int vtno = *((int *) arg); | |
203 | ||
204 | if (vtno != xf86Info.vtno) { | |
205 | if (!xf86VTActivate(vtno)) { | |
206 | ErrorF("Failed to switch from vt%02d to vt%02d: %s\n", | |
207 | xf86Info.vtno, vtno, strerror(errno)); | |
208 | } | |
209 | } | |
210 | } | |
211 | break; | |
212 | case ACTION_SWITCHSCREEN_NEXT: | |
213 | if (VTSwitchEnabled && !xf86Info.dontVTSwitch) { | |
214 | if (!xf86VTActivate(xf86Info.vtno + 1)) { | |
215 | /* If first try failed, assume this is the last VT and | |
216 | * try wrapping around to the first vt. | |
217 | */ | |
218 | if (!xf86VTActivate(1)) { | |
219 | ErrorF("Failed to switch from vt%02d to next vt: %s\n", | |
220 | xf86Info.vtno, strerror(errno)); | |
221 | } | |
222 | } | |
223 | } | |
224 | break; | |
225 | case ACTION_SWITCHSCREEN_PREV: | |
226 | if (VTSwitchEnabled && !xf86Info.dontVTSwitch && xf86Info.vtno > 0) { | |
227 | if (!xf86VTActivate(xf86Info.vtno - 1)) { | |
228 | /* Don't know what the maximum VT is, so can't wrap around */ | |
229 | ErrorF("Failed to switch from vt%02d to previous vt: %s\n", | |
230 | xf86Info.vtno, strerror(errno)); | |
231 | } | |
232 | } | |
233 | break; | |
234 | default: | |
235 | break; | |
236 | } | |
237 | } | |
238 | ||
239 | /* | |
240 | * xf86Wakeup -- | |
241 | * Os wakeup handler. | |
242 | */ | |
243 | ||
244 | /* ARGSUSED */ | |
245 | void | |
246 | xf86Wakeup(pointer blockData, int err, pointer pReadmask) | |
247 | { | |
248 | fd_set *LastSelectMask = (fd_set *) pReadmask; | |
249 | fd_set devicesWithInput; | |
250 | InputInfoPtr pInfo; | |
251 | ||
252 | if (err >= 0) { | |
253 | ||
254 | XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices); | |
255 | if (XFD_ANYSET(&devicesWithInput)) { | |
256 | pInfo = xf86InputDevs; | |
257 | while (pInfo) { | |
258 | if (pInfo->read_input && pInfo->fd >= 0 && | |
259 | (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) { | |
260 | OsBlockSIGIO(); | |
261 | ||
262 | /* | |
263 | * Remove the descriptior from the set because more than one | |
264 | * device may share the same file descriptor. | |
265 | */ | |
266 | FD_CLR(pInfo->fd, &devicesWithInput); | |
267 | ||
268 | pInfo->read_input(pInfo); | |
269 | OsReleaseSIGIO(); | |
270 | } | |
271 | pInfo = pInfo->next; | |
272 | } | |
273 | } | |
274 | } | |
275 | ||
276 | if (err >= 0) { /* we don't want the handlers called if select() */ | |
277 | IHPtr ih, ih_tmp; /* returned with an error condition, do we? */ | |
278 | ||
279 | nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) { | |
280 | if (ih->enabled && ih->fd >= 0 && ih->ihproc && | |
281 | (FD_ISSET(ih->fd, ((fd_set *) pReadmask)) != 0)) { | |
282 | ih->ihproc(ih->fd, ih->data); | |
283 | } | |
284 | } | |
285 | } | |
286 | ||
287 | if (xf86VTSwitchPending()) | |
288 | xf86VTSwitch(); | |
289 | } | |
290 | ||
291 | /* | |
292 | * xf86SigioReadInput -- | |
293 | * signal handler for the SIGIO signal. | |
294 | */ | |
295 | static void | |
296 | xf86SigioReadInput(int fd, void *closure) | |
297 | { | |
298 | int errno_save = errno; | |
299 | InputInfoPtr pInfo = closure; | |
300 | ||
301 | pInfo->read_input(pInfo); | |
302 | ||
303 | errno = errno_save; | |
304 | } | |
305 | ||
306 | /* | |
307 | * xf86AddEnabledDevice -- | |
308 | * | |
309 | */ | |
310 | void | |
311 | xf86AddEnabledDevice(InputInfoPtr pInfo) | |
312 | { | |
313 | if (!xf86InstallSIGIOHandler(pInfo->fd, xf86SigioReadInput, pInfo)) { | |
314 | AddEnabledDevice(pInfo->fd); | |
315 | } | |
316 | } | |
317 | ||
318 | /* | |
319 | * xf86RemoveEnabledDevice -- | |
320 | * | |
321 | */ | |
322 | void | |
323 | xf86RemoveEnabledDevice(InputInfoPtr pInfo) | |
324 | { | |
325 | if (!xf86RemoveSIGIOHandler(pInfo->fd)) { | |
326 | RemoveEnabledDevice(pInfo->fd); | |
327 | } | |
328 | } | |
329 | ||
330 | static int *xf86SignalIntercept = NULL; | |
331 | ||
332 | void | |
333 | xf86InterceptSignals(int *signo) | |
334 | { | |
335 | if ((xf86SignalIntercept = signo)) | |
336 | *signo = -1; | |
337 | } | |
338 | ||
339 | static void (*xf86SigIllHandler) (void) = NULL; | |
340 | ||
341 | void | |
342 | xf86InterceptSigIll(void (*sigillhandler) (void)) | |
343 | { | |
344 | xf86SigIllHandler = sigillhandler; | |
345 | } | |
346 | ||
347 | /* | |
348 | * xf86SigWrapper -- | |
349 | * Catch unexpected signals and exit or continue cleanly. | |
350 | */ | |
351 | int | |
352 | xf86SigWrapper(int signo) | |
353 | { | |
354 | if ((signo == SIGILL) && xf86SigIllHandler) { | |
355 | (*xf86SigIllHandler) (); | |
356 | return 0; /* continue */ | |
357 | } | |
358 | ||
359 | if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) { | |
360 | *xf86SignalIntercept = signo; | |
361 | return 0; /* continue */ | |
362 | } | |
363 | ||
364 | xf86Info.caughtSignal = TRUE; | |
365 | return 1; /* abort */ | |
366 | } | |
367 | ||
368 | /* | |
369 | * xf86PrintBacktrace -- | |
370 | * Print a stack backtrace for debugging purposes. | |
371 | */ | |
372 | void | |
373 | xf86PrintBacktrace(void) | |
374 | { | |
375 | xorg_backtrace(); | |
376 | } | |
377 | ||
378 | static void | |
379 | xf86ReleaseKeys(DeviceIntPtr pDev) | |
380 | { | |
381 | KeyClassPtr keyc; | |
382 | int i; | |
383 | ||
384 | if (!pDev || !pDev->key) | |
385 | return; | |
386 | ||
387 | keyc = pDev->key; | |
388 | ||
389 | /* | |
390 | * Hmm... here is the biggest hack of every time ! | |
391 | * It may be possible that a switch-vt procedure has finished BEFORE | |
392 | * you released all keys neccessary to do this. That peculiar behavior | |
393 | * can fool the X-server pretty much, cause it assumes that some keys | |
394 | * were not released. TWM may stuck alsmost completly.... | |
395 | * OK, what we are doing here is after returning from the vt-switch | |
396 | * exeplicitely unrelease all keyboard keys before the input-devices | |
397 | * are reenabled. | |
398 | */ | |
399 | ||
400 | for (i = keyc->xkbInfo->desc->min_key_code; | |
401 | i < keyc->xkbInfo->desc->max_key_code; i++) { | |
402 | if (key_is_down(pDev, i, KEY_POSTED)) { | |
403 | OsBlockSIGIO(); | |
404 | QueueKeyboardEvents(pDev, KeyRelease, i, NULL); | |
405 | OsReleaseSIGIO(); | |
406 | } | |
407 | } | |
408 | } | |
409 | ||
410 | /* | |
411 | * xf86VTSwitch -- | |
412 | * Handle requests for switching the vt. | |
413 | */ | |
414 | static void | |
415 | xf86VTSwitch(void) | |
416 | { | |
417 | int i; | |
418 | InputInfoPtr pInfo; | |
419 | IHPtr ih; | |
420 | ||
421 | DebugF("xf86VTSwitch()\n"); | |
422 | ||
423 | #ifdef XFreeXDGA | |
424 | if (!DGAVTSwitch()) | |
425 | return; | |
426 | #endif | |
427 | ||
428 | /* | |
429 | * Since all screens are currently all in the same state it is sufficient | |
430 | * check the first. This might change in future. | |
431 | */ | |
432 | if (xf86VTOwner()) { | |
433 | ||
434 | DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n", | |
435 | BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE)); | |
436 | #ifdef DPMSExtension | |
437 | if (DPMSPowerLevel != DPMSModeOn) | |
438 | DPMSSet(serverClient, DPMSModeOn); | |
439 | #endif | |
440 | for (i = 0; i < xf86NumScreens; i++) { | |
441 | if (!(dispatchException & DE_TERMINATE)) | |
442 | if (xf86Screens[i]->EnableDisableFBAccess) | |
443 | (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE); | |
444 | } | |
445 | ||
446 | /* | |
447 | * Keep the order: Disable Device > LeaveVT | |
448 | * EnterVT > EnableDevice | |
449 | */ | |
450 | for (ih = InputHandlers; ih; ih = ih->next) { | |
451 | if (ih->is_input) | |
452 | xf86DisableInputHandler(ih); | |
453 | else | |
454 | xf86DisableGeneralHandler(ih); | |
455 | } | |
456 | for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) { | |
457 | if (pInfo->dev) { | |
458 | if (!pInfo->dev->enabled) | |
459 | pInfo->flags |= XI86_DEVICE_DISABLED; | |
460 | xf86ReleaseKeys(pInfo->dev); | |
461 | ProcessInputEvents(); | |
462 | DisableDevice(pInfo->dev, TRUE); | |
463 | } | |
464 | } | |
465 | ||
466 | OsBlockSIGIO(); | |
467 | for (i = 0; i < xf86NumScreens; i++) | |
468 | xf86Screens[i]->LeaveVT(xf86Screens[i]); | |
469 | for (i = 0; i < xf86NumGPUScreens; i++) | |
470 | xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]); | |
471 | ||
472 | xf86AccessLeave(); /* We need this here, otherwise */ | |
473 | ||
474 | if (!xf86VTSwitchAway()) { | |
475 | /* | |
476 | * switch failed | |
477 | */ | |
478 | ||
479 | DebugF("xf86VTSwitch: Leave failed\n"); | |
480 | xf86AccessEnter(); | |
481 | for (i = 0; i < xf86NumScreens; i++) { | |
482 | if (!xf86Screens[i]->EnterVT(xf86Screens[i])) | |
483 | FatalError("EnterVT failed for screen %d\n", i); | |
484 | } | |
485 | for (i = 0; i < xf86NumGPUScreens; i++) { | |
486 | if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i])) | |
487 | FatalError("EnterVT failed for gpu screen %d\n", i); | |
488 | } | |
489 | if (!(dispatchException & DE_TERMINATE)) { | |
490 | for (i = 0; i < xf86NumScreens; i++) { | |
491 | if (xf86Screens[i]->EnableDisableFBAccess) | |
492 | (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); | |
493 | } | |
494 | } | |
495 | dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); | |
496 | ||
497 | pInfo = xf86InputDevs; | |
498 | while (pInfo) { | |
499 | if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0) | |
500 | EnableDevice(pInfo->dev, TRUE); | |
501 | pInfo->flags &= ~XI86_DEVICE_DISABLED; | |
502 | pInfo = pInfo->next; | |
503 | } | |
504 | for (ih = InputHandlers; ih; ih = ih->next) { | |
505 | if (ih->is_input) | |
506 | xf86EnableInputHandler(ih); | |
507 | else | |
508 | xf86EnableGeneralHandler(ih); | |
509 | } | |
510 | OsReleaseSIGIO(); | |
511 | ||
512 | } | |
513 | else { | |
514 | #ifdef XF86PM | |
515 | if (xf86OSPMClose) | |
516 | xf86OSPMClose(); | |
517 | xf86OSPMClose = NULL; | |
518 | #endif | |
519 | ||
520 | for (i = 0; i < xf86NumScreens; i++) { | |
521 | /* | |
522 | * zero all access functions to | |
523 | * trap calls when switched away. | |
524 | */ | |
525 | xf86Screens[i]->vtSema = FALSE; | |
526 | } | |
527 | if (xorgHWAccess) | |
528 | xf86DisableIO(); | |
529 | } | |
530 | } | |
531 | else { | |
532 | DebugF("xf86VTSwitch: Entering\n"); | |
533 | if (!xf86VTSwitchTo()) | |
534 | return; | |
535 | ||
536 | #ifdef XF86PM | |
537 | xf86OSPMClose = xf86OSPMOpen(); | |
538 | #endif | |
539 | ||
540 | if (xorgHWAccess) | |
541 | xf86EnableIO(); | |
542 | xf86AccessEnter(); | |
543 | for (i = 0; i < xf86NumScreens; i++) { | |
544 | xf86Screens[i]->vtSema = TRUE; | |
545 | if (!xf86Screens[i]->EnterVT(xf86Screens[i])) | |
546 | FatalError("EnterVT failed for screen %d\n", i); | |
547 | } | |
548 | for (i = 0; i < xf86NumGPUScreens; i++) { | |
549 | xf86GPUScreens[i]->vtSema = TRUE; | |
550 | if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i])) | |
551 | FatalError("EnterVT failed for gpu screen %d\n", i); | |
552 | } | |
553 | for (i = 0; i < xf86NumScreens; i++) { | |
554 | if (xf86Screens[i]->EnableDisableFBAccess) | |
555 | (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE); | |
556 | } | |
557 | ||
558 | /* Turn screen saver off when switching back */ | |
559 | dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); | |
560 | ||
561 | pInfo = xf86InputDevs; | |
562 | while (pInfo) { | |
563 | if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0) | |
564 | EnableDevice(pInfo->dev, TRUE); | |
565 | pInfo->flags &= ~XI86_DEVICE_DISABLED; | |
566 | pInfo = pInfo->next; | |
567 | } | |
568 | ||
569 | for (ih = InputHandlers; ih; ih = ih->next) { | |
570 | if (ih->is_input) | |
571 | xf86EnableInputHandler(ih); | |
572 | else | |
573 | xf86EnableGeneralHandler(ih); | |
574 | } | |
575 | #ifdef XSERVER_PLATFORM_BUS | |
576 | /* check for any new output devices */ | |
577 | xf86platformVTProbe(); | |
578 | #endif | |
579 | ||
580 | OsReleaseSIGIO(); | |
581 | } | |
582 | } | |
583 | ||
584 | /* Input handler registration */ | |
585 | ||
586 | static pointer | |
587 | addInputHandler(int fd, InputHandlerProc proc, pointer data) | |
588 | { | |
589 | IHPtr ih; | |
590 | ||
591 | if (fd < 0 || !proc) | |
592 | return NULL; | |
593 | ||
594 | ih = calloc(sizeof(*ih), 1); | |
595 | if (!ih) | |
596 | return NULL; | |
597 | ||
598 | ih->fd = fd; | |
599 | ih->ihproc = proc; | |
600 | ih->data = data; | |
601 | ih->enabled = TRUE; | |
602 | ||
603 | ih->next = InputHandlers; | |
604 | InputHandlers = ih; | |
605 | ||
606 | return ih; | |
607 | } | |
608 | ||
609 | pointer | |
610 | xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data) | |
611 | { | |
612 | IHPtr ih = addInputHandler(fd, proc, data); | |
613 | ||
614 | if (ih) { | |
615 | AddEnabledDevice(fd); | |
616 | ih->is_input = TRUE; | |
617 | } | |
618 | return ih; | |
619 | } | |
620 | ||
621 | pointer | |
622 | xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data) | |
623 | { | |
624 | IHPtr ih = addInputHandler(fd, proc, data); | |
625 | ||
626 | if (ih) | |
627 | AddGeneralSocket(fd); | |
628 | return ih; | |
629 | } | |
630 | ||
631 | /** | |
632 | * Set the handler for the console's fd. Replaces (and returns) the previous | |
633 | * handler or NULL, whichever appropriate. | |
634 | * proc may be NULL if the server should not handle events on the console. | |
635 | */ | |
636 | InputHandlerProc | |
637 | xf86SetConsoleHandler(InputHandlerProc proc, pointer data) | |
638 | { | |
639 | static IHPtr handler = NULL; | |
640 | InputHandlerProc old_proc = NULL; | |
641 | ||
642 | if (handler) { | |
643 | old_proc = handler->ihproc; | |
644 | xf86RemoveGeneralHandler(handler); | |
645 | } | |
646 | ||
647 | handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data); | |
648 | ||
649 | return old_proc; | |
650 | } | |
651 | ||
652 | static void | |
653 | removeInputHandler(IHPtr ih) | |
654 | { | |
655 | IHPtr p; | |
656 | ||
657 | if (ih == InputHandlers) | |
658 | InputHandlers = ih->next; | |
659 | else { | |
660 | p = InputHandlers; | |
661 | while (p && p->next != ih) | |
662 | p = p->next; | |
663 | if (ih) | |
664 | p->next = ih->next; | |
665 | } | |
666 | free(ih); | |
667 | } | |
668 | ||
669 | int | |
670 | xf86RemoveInputHandler(pointer handler) | |
671 | { | |
672 | IHPtr ih; | |
673 | int fd; | |
674 | ||
675 | if (!handler) | |
676 | return -1; | |
677 | ||
678 | ih = handler; | |
679 | fd = ih->fd; | |
680 | ||
681 | if (ih->fd >= 0) | |
682 | RemoveEnabledDevice(ih->fd); | |
683 | removeInputHandler(ih); | |
684 | ||
685 | return fd; | |
686 | } | |
687 | ||
688 | int | |
689 | xf86RemoveGeneralHandler(pointer handler) | |
690 | { | |
691 | IHPtr ih; | |
692 | int fd; | |
693 | ||
694 | if (!handler) | |
695 | return -1; | |
696 | ||
697 | ih = handler; | |
698 | fd = ih->fd; | |
699 | ||
700 | if (ih->fd >= 0) | |
701 | RemoveGeneralSocket(ih->fd); | |
702 | removeInputHandler(ih); | |
703 | ||
704 | return fd; | |
705 | } | |
706 | ||
707 | void | |
708 | xf86DisableInputHandler(pointer handler) | |
709 | { | |
710 | IHPtr ih; | |
711 | ||
712 | if (!handler) | |
713 | return; | |
714 | ||
715 | ih = handler; | |
716 | ih->enabled = FALSE; | |
717 | if (ih->fd >= 0) | |
718 | RemoveEnabledDevice(ih->fd); | |
719 | } | |
720 | ||
721 | void | |
722 | xf86DisableGeneralHandler(pointer handler) | |
723 | { | |
724 | IHPtr ih; | |
725 | ||
726 | if (!handler) | |
727 | return; | |
728 | ||
729 | ih = handler; | |
730 | ih->enabled = FALSE; | |
731 | if (ih->fd >= 0) | |
732 | RemoveGeneralSocket(ih->fd); | |
733 | } | |
734 | ||
735 | void | |
736 | xf86EnableInputHandler(pointer handler) | |
737 | { | |
738 | IHPtr ih; | |
739 | ||
740 | if (!handler) | |
741 | return; | |
742 | ||
743 | ih = handler; | |
744 | ih->enabled = TRUE; | |
745 | if (ih->fd >= 0) | |
746 | AddEnabledDevice(ih->fd); | |
747 | } | |
748 | ||
749 | void | |
750 | xf86EnableGeneralHandler(pointer handler) | |
751 | { | |
752 | IHPtr ih; | |
753 | ||
754 | if (!handler) | |
755 | return; | |
756 | ||
757 | ih = handler; | |
758 | ih->enabled = TRUE; | |
759 | if (ih->fd >= 0) | |
760 | AddGeneralSocket(ih->fd); | |
761 | } | |
762 | ||
763 | /* | |
764 | * As used currently by the DRI, the return value is ignored. | |
765 | */ | |
766 | Bool | |
767 | xf86EnableVTSwitch(Bool new) | |
768 | { | |
769 | static Bool def = TRUE; | |
770 | Bool old; | |
771 | ||
772 | old = VTSwitchEnabled; | |
773 | if (!new) { | |
774 | /* Disable VT switching */ | |
775 | def = VTSwitchEnabled; | |
776 | VTSwitchEnabled = FALSE; | |
777 | } | |
778 | else { | |
779 | /* Restore VT switching to default */ | |
780 | VTSwitchEnabled = def; | |
781 | } | |
782 | return old; | |
783 | } | |
784 | ||
785 | void | |
786 | DDXRingBell(int volume, int pitch, int duration) | |
787 | { | |
788 | xf86OSRingBell(volume, pitch, duration); | |
789 | } | |
790 | ||
791 | Bool | |
792 | xf86VTOwner(void) | |
793 | { | |
794 | /* at system startup xf86Screens[0] won't be set - but we will own the VT */ | |
795 | if (xf86NumScreens == 0) | |
796 | return TRUE; | |
797 | return xf86Screens[0]->vtSema; | |
798 | } |