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/Xproto.h>
58 #include <X11/Xatom.h>
59 #include "misc.h"
60 #include "xf86.h"
61 #include "xf86Priv.h"
62 #define XF86_OS_PRIVS
63 #include "xf86_OSlib.h"
64 #include <X11/keysym.h>
65
66 #ifdef XFreeXDGA
67 #include "dgaproc.h"
68 #endif
69
70 #include <X11/extensions/XI.h>
71 #include <X11/extensions/XIproto.h>
72 #include "inputstr.h"
73 #include "xf86Xinput.h"
74
75 #include "mi.h"
76 #include "mipointer.h"
77
78 #include "xkbsrv.h"
79 #include "xkbstr.h"
80
81 #ifdef DPMSExtension
82 #include <X11/extensions/dpmsconst.h>
83 #include "dpmsproc.h"
84 #endif
85
86 #include "xf86platformBus.h"
87 #include "systemd-logind.h"
88
89 #ifdef XF86PM
90 extern void (*xf86OSPMClose) (void);
91 #endif
92
93 static void xf86VTSwitch(void);
94
95 /*
96 * Allow arbitrary drivers or other XFree86 code to register with our main
97 * Wakeup handler.
98 */
99 typedef struct x_IHRec {
100 int fd;
101 InputHandlerProc ihproc;
102 void *data;
103 Bool enabled;
104 Bool is_input;
105 struct x_IHRec *next;
106 } IHRec, *IHPtr;
107
108 static IHPtr InputHandlers = NULL;
109
110 Bool
LegalModifier(unsigned int key,DeviceIntPtr pDev)111 LegalModifier(unsigned int key, DeviceIntPtr pDev)
112 {
113 return TRUE;
114 }
115
116 /*
117 * TimeSinceLastInputEvent --
118 * Function used for screensaver purposes by the os module. Returns the
119 * time in milliseconds since there last was any input.
120 */
121 int
TimeSinceLastInputEvent(void)122 TimeSinceLastInputEvent(void)
123 {
124 if (xf86Info.lastEventTime == 0) {
125 xf86Info.lastEventTime = GetTimeInMillis();
126 }
127 return GetTimeInMillis() - xf86Info.lastEventTime;
128 }
129
130 /*
131 * SetTimeSinceLastInputEvent --
132 * Set the lastEventTime to now.
133 */
134 void
SetTimeSinceLastInputEvent(void)135 SetTimeSinceLastInputEvent(void)
136 {
137 xf86Info.lastEventTime = GetTimeInMillis();
138 }
139
140 /*
141 * ProcessInputEvents --
142 * Retrieve all waiting input events and pass them to DIX in their
143 * correct chronological order. Only reads from the system pointer
144 * and keyboard.
145 */
146 void
ProcessInputEvents(void)147 ProcessInputEvents(void)
148 {
149 int x, y;
150
151 mieqProcessInputEvents();
152
153 /* FIXME: This is a problem if we have multiple pointers */
154 miPointerGetPosition(inputInfo.pointer, &x, &y);
155
156 xf86SetViewport(xf86Info.currentScreen, x, y);
157 }
158
159 /*
160 * Handle keyboard events that cause some kind of "action"
161 * (i.e., server termination, video mode changes, VT switches, etc.)
162 */
163 void
xf86ProcessActionEvent(ActionEvent action,void * arg)164 xf86ProcessActionEvent(ActionEvent action, void *arg)
165 {
166 DebugF("ProcessActionEvent(%d,%p)\n", (int) action, arg);
167 switch (action) {
168 case ACTION_TERMINATE:
169 if (!xf86Info.dontZap) {
170 xf86Msg(X_INFO, "Server zapped. Shutting down.\n");
171 #ifdef XFreeXDGA
172 DGAShutdown();
173 #endif
174 GiveUp(0);
175 }
176 break;
177 case ACTION_NEXT_MODE:
178 if (!xf86Info.dontZoom)
179 xf86ZoomViewport(xf86Info.currentScreen, 1);
180 break;
181 case ACTION_PREV_MODE:
182 if (!xf86Info.dontZoom)
183 xf86ZoomViewport(xf86Info.currentScreen, -1);
184 break;
185 case ACTION_SWITCHSCREEN:
186 if (!xf86Info.dontVTSwitch && arg) {
187 int vtno = *((int *) arg);
188
189 if (vtno != xf86Info.vtno) {
190 if (!xf86VTActivate(vtno)) {
191 ErrorF("Failed to switch from vt%02d to vt%02d: %s\n",
192 xf86Info.vtno, vtno, strerror(errno));
193 }
194 }
195 }
196 break;
197 case ACTION_SWITCHSCREEN_NEXT:
198 if (!xf86Info.dontVTSwitch) {
199 if (!xf86VTActivate(xf86Info.vtno + 1)) {
200 /* If first try failed, assume this is the last VT and
201 * try wrapping around to the first vt.
202 */
203 if (!xf86VTActivate(1)) {
204 ErrorF("Failed to switch from vt%02d to next vt: %s\n",
205 xf86Info.vtno, strerror(errno));
206 }
207 }
208 }
209 break;
210 case ACTION_SWITCHSCREEN_PREV:
211 if (!xf86Info.dontVTSwitch && xf86Info.vtno > 0) {
212 if (!xf86VTActivate(xf86Info.vtno - 1)) {
213 /* Don't know what the maximum VT is, so can't wrap around */
214 ErrorF("Failed to switch from vt%02d to previous vt: %s\n",
215 xf86Info.vtno, strerror(errno));
216 }
217 }
218 break;
219 default:
220 break;
221 }
222 }
223
224 /*
225 * xf86Wakeup --
226 * Os wakeup handler.
227 */
228
229 /* ARGSUSED */
230 void
xf86Wakeup(void * blockData,int err)231 xf86Wakeup(void *blockData, int err)
232 {
233 if (xf86VTSwitchPending())
234 xf86VTSwitch();
235 }
236
237 /*
238 * xf86ReadInput --
239 * input thread handler
240 */
241
242 static void
xf86ReadInput(int fd,int ready,void * closure)243 xf86ReadInput(int fd, int ready, void *closure)
244 {
245 InputInfoPtr pInfo = closure;
246
247 pInfo->read_input(pInfo);
248 }
249
250 /*
251 * xf86AddEnabledDevice --
252 *
253 */
254 void
xf86AddEnabledDevice(InputInfoPtr pInfo)255 xf86AddEnabledDevice(InputInfoPtr pInfo)
256 {
257 InputThreadRegisterDev(pInfo->fd, xf86ReadInput, pInfo);
258 }
259
260 /*
261 * xf86RemoveEnabledDevice --
262 *
263 */
264 void
xf86RemoveEnabledDevice(InputInfoPtr pInfo)265 xf86RemoveEnabledDevice(InputInfoPtr pInfo)
266 {
267 InputThreadUnregisterDev(pInfo->fd);
268 }
269
270 /*
271 * xf86PrintBacktrace --
272 * Print a stack backtrace for debugging purposes.
273 */
274 void
xf86PrintBacktrace(void)275 xf86PrintBacktrace(void)
276 {
277 xorg_backtrace();
278 }
279
280 static void
xf86ReleaseKeys(DeviceIntPtr pDev)281 xf86ReleaseKeys(DeviceIntPtr pDev)
282 {
283 KeyClassPtr keyc;
284 int i;
285
286 if (!pDev || !pDev->key)
287 return;
288
289 keyc = pDev->key;
290
291 /*
292 * Hmm... here is the biggest hack of every time !
293 * It may be possible that a switch-vt procedure has finished BEFORE
294 * you released all keys neccessary to do this. That peculiar behavior
295 * can fool the X-server pretty much, cause it assumes that some keys
296 * were not released. TWM may stuck alsmost completly....
297 * OK, what we are doing here is after returning from the vt-switch
298 * exeplicitely unrelease all keyboard keys before the input-devices
299 * are reenabled.
300 */
301
302 for (i = keyc->xkbInfo->desc->min_key_code;
303 i < keyc->xkbInfo->desc->max_key_code; i++) {
304 if (key_is_down(pDev, i, KEY_POSTED)) {
305 input_lock();
306 QueueKeyboardEvents(pDev, KeyRelease, i);
307 input_unlock();
308 }
309 }
310 }
311
312 void
xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo)313 xf86DisableInputDeviceForVTSwitch(InputInfoPtr pInfo)
314 {
315 if (!pInfo->dev)
316 return;
317
318 if (!pInfo->dev->enabled)
319 pInfo->flags |= XI86_DEVICE_DISABLED;
320
321 xf86ReleaseKeys(pInfo->dev);
322 ProcessInputEvents();
323 DisableDevice(pInfo->dev, TRUE);
324 }
325
326 void
xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)327 xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo)
328 {
329 if (pInfo->dev && (pInfo->flags & XI86_DEVICE_DISABLED) == 0)
330 EnableDevice(pInfo->dev, TRUE);
331 pInfo->flags &= ~XI86_DEVICE_DISABLED;
332 }
333
334 /*
335 * xf86UpdateHasVTProperty --
336 * Update a flag property on the root window to say whether the server VT
337 * is currently the active one as some clients need to know this.
338 */
339 static void
xf86UpdateHasVTProperty(Bool hasVT)340 xf86UpdateHasVTProperty(Bool hasVT)
341 {
342 Atom property_name;
343 int32_t value = hasVT ? 1 : 0;
344 int i;
345
346 property_name = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1,
347 FALSE);
348 if (property_name == BAD_RESOURCE)
349 FatalError("Failed to retrieve \"HAS_VT\" atom\n");
350 for (i = 0; i < xf86NumScreens; i++) {
351 dixChangeWindowProperty(serverClient,
352 xf86ScrnToScreen(xf86Screens[i])->root,
353 property_name, XA_INTEGER, 32,
354 PropModeReplace, 1, &value, TRUE);
355 }
356 }
357
358 void
xf86VTLeave(void)359 xf86VTLeave(void)
360 {
361 int i;
362 InputInfoPtr pInfo;
363 IHPtr ih;
364
365 DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
366 BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
367 #ifdef DPMSExtension
368 if (DPMSPowerLevel != DPMSModeOn)
369 DPMSSet(serverClient, DPMSModeOn);
370 #endif
371 for (i = 0; i < xf86NumScreens; i++) {
372 if (!(dispatchException & DE_TERMINATE))
373 if (xf86Screens[i]->EnableDisableFBAccess)
374 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], FALSE);
375 }
376
377 /*
378 * Keep the order: Disable Device > LeaveVT
379 * EnterVT > EnableDevice
380 */
381 for (ih = InputHandlers; ih; ih = ih->next) {
382 if (ih->is_input)
383 xf86DisableInputHandler(ih);
384 else
385 xf86DisableGeneralHandler(ih);
386 }
387 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
388 xf86DisableInputDeviceForVTSwitch(pInfo);
389
390 input_lock();
391 for (i = 0; i < xf86NumScreens; i++)
392 xf86Screens[i]->LeaveVT(xf86Screens[i]);
393 for (i = 0; i < xf86NumGPUScreens; i++)
394 xf86GPUScreens[i]->LeaveVT(xf86GPUScreens[i]);
395
396 if (!xf86VTSwitchAway())
397 goto switch_failed;
398
399 #ifdef XF86PM
400 if (xf86OSPMClose)
401 xf86OSPMClose();
402 xf86OSPMClose = NULL;
403 #endif
404
405 for (i = 0; i < xf86NumScreens; i++) {
406 /*
407 * zero all access functions to
408 * trap calls when switched away.
409 */
410 xf86Screens[i]->vtSema = FALSE;
411 }
412 if (xorgHWAccess)
413 xf86DisableIO();
414
415 xf86UpdateHasVTProperty(FALSE);
416
417 return;
418
419 switch_failed:
420 DebugF("xf86VTSwitch: Leave failed\n");
421 for (i = 0; i < xf86NumScreens; i++) {
422 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
423 FatalError("EnterVT failed for screen %d\n", i);
424 }
425 for (i = 0; i < xf86NumGPUScreens; i++) {
426 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
427 FatalError("EnterVT failed for gpu screen %d\n", i);
428 }
429 if (!(dispatchException & DE_TERMINATE)) {
430 for (i = 0; i < xf86NumScreens; i++) {
431 if (xf86Screens[i]->EnableDisableFBAccess)
432 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
433 }
434 }
435 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
436
437 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next)
438 xf86EnableInputDeviceForVTSwitch(pInfo);
439 for (ih = InputHandlers; ih; ih = ih->next) {
440 if (ih->is_input)
441 xf86EnableInputHandler(ih);
442 else
443 xf86EnableGeneralHandler(ih);
444 }
445 input_unlock();
446 }
447
448 void
xf86VTEnter(void)449 xf86VTEnter(void)
450 {
451 int i;
452 InputInfoPtr pInfo;
453 IHPtr ih;
454
455 DebugF("xf86VTSwitch: Entering\n");
456 if (!xf86VTSwitchTo())
457 return;
458
459 #ifdef XF86PM
460 xf86OSPMClose = xf86OSPMOpen();
461 #endif
462
463 if (xorgHWAccess)
464 xf86EnableIO();
465 for (i = 0; i < xf86NumScreens; i++) {
466 xf86Screens[i]->vtSema = TRUE;
467 if (!xf86Screens[i]->EnterVT(xf86Screens[i]))
468 FatalError("EnterVT failed for screen %d\n", i);
469 }
470 for (i = 0; i < xf86NumGPUScreens; i++) {
471 xf86GPUScreens[i]->vtSema = TRUE;
472 if (!xf86GPUScreens[i]->EnterVT(xf86GPUScreens[i]))
473 FatalError("EnterVT failed for gpu screen %d\n", i);
474 }
475 for (i = 0; i < xf86NumScreens; i++) {
476 if (xf86Screens[i]->EnableDisableFBAccess)
477 (*xf86Screens[i]->EnableDisableFBAccess) (xf86Screens[i], TRUE);
478 }
479
480 /* Turn screen saver off when switching back */
481 dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
482
483 for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
484 /* Devices with server managed fds get enabled on logind resume */
485 if (!(pInfo->flags & XI86_SERVER_FD))
486 xf86EnableInputDeviceForVTSwitch(pInfo);
487 }
488
489 for (ih = InputHandlers; ih; ih = ih->next) {
490 if (ih->is_input)
491 xf86EnableInputHandler(ih);
492 else
493 xf86EnableGeneralHandler(ih);
494 }
495 #ifdef XSERVER_PLATFORM_BUS
496 /* check for any new output devices */
497 xf86platformVTProbe();
498 #endif
499
500 xf86UpdateHasVTProperty(TRUE);
501
502 input_unlock();
503 }
504
505 /*
506 * xf86VTSwitch --
507 * Handle requests for switching the vt.
508 */
509 static void
xf86VTSwitch(void)510 xf86VTSwitch(void)
511 {
512 DebugF("xf86VTSwitch()\n");
513
514 #ifdef XFreeXDGA
515 if (!DGAVTSwitch())
516 return;
517 #endif
518
519 /*
520 * Since all screens are currently all in the same state it is sufficient
521 * check the first. This might change in future.
522 *
523 * VTLeave is always handled here (VT_PROCESS guarantees this is safe),
524 * if we use systemd_logind xf86VTEnter() gets called by systemd-logind.c
525 * once it has resumed all drm nodes.
526 */
527 if (xf86VTOwner())
528 xf86VTLeave();
529 else if (!systemd_logind_controls_session())
530 xf86VTEnter();
531 }
532
533 /* Input handler registration */
534
535 static void
xf86InputHandlerNotify(int fd,int ready,void * data)536 xf86InputHandlerNotify(int fd, int ready, void *data)
537 {
538 IHPtr ih = data;
539
540 if (ih->enabled && ih->fd >= 0 && ih->ihproc) {
541 ih->ihproc(ih->fd, ih->data);
542 }
543 }
544
545 static void *
addInputHandler(int fd,InputHandlerProc proc,void * data)546 addInputHandler(int fd, InputHandlerProc proc, void *data)
547 {
548 IHPtr ih;
549
550 if (fd < 0 || !proc)
551 return NULL;
552
553 ih = calloc(sizeof(*ih), 1);
554 if (!ih)
555 return NULL;
556
557 ih->fd = fd;
558 ih->ihproc = proc;
559 ih->data = data;
560 ih->enabled = TRUE;
561
562 if (!SetNotifyFd(fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih)) {
563 free(ih);
564 return NULL;
565 }
566
567 ih->next = InputHandlers;
568 InputHandlers = ih;
569
570 return ih;
571 }
572
573 void *
xf86AddInputHandler(int fd,InputHandlerProc proc,void * data)574 xf86AddInputHandler(int fd, InputHandlerProc proc, void *data)
575 {
576 IHPtr ih = addInputHandler(fd, proc, data);
577
578 if (ih)
579 ih->is_input = TRUE;
580 return ih;
581 }
582
583 void *
xf86AddGeneralHandler(int fd,InputHandlerProc proc,void * data)584 xf86AddGeneralHandler(int fd, InputHandlerProc proc, void *data)
585 {
586 IHPtr ih = addInputHandler(fd, proc, data);
587
588 return ih;
589 }
590
591 /**
592 * Set the handler for the console's fd. Replaces (and returns) the previous
593 * handler or NULL, whichever appropriate.
594 * proc may be NULL if the server should not handle events on the console.
595 */
596 InputHandlerProc
xf86SetConsoleHandler(InputHandlerProc proc,void * data)597 xf86SetConsoleHandler(InputHandlerProc proc, void *data)
598 {
599 static IHPtr handler = NULL;
600 InputHandlerProc old_proc = NULL;
601
602 if (handler) {
603 old_proc = handler->ihproc;
604 xf86RemoveGeneralHandler(handler);
605 }
606
607 handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
608
609 return old_proc;
610 }
611
612 static void
removeInputHandler(IHPtr ih)613 removeInputHandler(IHPtr ih)
614 {
615 IHPtr p;
616
617 if (ih->fd >= 0)
618 RemoveNotifyFd(ih->fd);
619 if (ih == InputHandlers)
620 InputHandlers = ih->next;
621 else {
622 p = InputHandlers;
623 while (p && p->next != ih)
624 p = p->next;
625 if (ih)
626 p->next = ih->next;
627 }
628 free(ih);
629 }
630
631 int
xf86RemoveInputHandler(void * handler)632 xf86RemoveInputHandler(void *handler)
633 {
634 IHPtr ih;
635 int fd;
636
637 if (!handler)
638 return -1;
639
640 ih = handler;
641 fd = ih->fd;
642
643 removeInputHandler(ih);
644
645 return fd;
646 }
647
648 int
xf86RemoveGeneralHandler(void * handler)649 xf86RemoveGeneralHandler(void *handler)
650 {
651 IHPtr ih;
652 int fd;
653
654 if (!handler)
655 return -1;
656
657 ih = handler;
658 fd = ih->fd;
659
660 removeInputHandler(ih);
661
662 return fd;
663 }
664
665 void
xf86DisableInputHandler(void * handler)666 xf86DisableInputHandler(void *handler)
667 {
668 IHPtr ih;
669
670 if (!handler)
671 return;
672
673 ih = handler;
674 ih->enabled = FALSE;
675 if (ih->fd >= 0)
676 RemoveNotifyFd(ih->fd);
677 }
678
679 void
xf86DisableGeneralHandler(void * handler)680 xf86DisableGeneralHandler(void *handler)
681 {
682 IHPtr ih;
683
684 if (!handler)
685 return;
686
687 ih = handler;
688 ih->enabled = FALSE;
689 if (ih->fd >= 0)
690 RemoveNotifyFd(ih->fd);
691 }
692
693 void
xf86EnableInputHandler(void * handler)694 xf86EnableInputHandler(void *handler)
695 {
696 IHPtr ih;
697
698 if (!handler)
699 return;
700
701 ih = handler;
702 ih->enabled = TRUE;
703 if (ih->fd >= 0)
704 SetNotifyFd(ih->fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih);
705 }
706
707 void
xf86EnableGeneralHandler(void * handler)708 xf86EnableGeneralHandler(void *handler)
709 {
710 IHPtr ih;
711
712 if (!handler)
713 return;
714
715 ih = handler;
716 ih->enabled = TRUE;
717 if (ih->fd >= 0)
718 SetNotifyFd(ih->fd, xf86InputHandlerNotify, X_NOTIFY_READ, ih);
719 }
720
721 void
DDXRingBell(int volume,int pitch,int duration)722 DDXRingBell(int volume, int pitch, int duration)
723 {
724 xf86OSRingBell(volume, pitch, duration);
725 }
726
727 Bool
xf86VTOwner(void)728 xf86VTOwner(void)
729 {
730 /* at system startup xf86Screens[0] won't be set - but we will own the VT */
731 if (xf86NumScreens == 0)
732 return TRUE;
733 return xf86Screens[0]->vtSema;
734 }
735