2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
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.
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.
24 * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
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:
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
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.
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).
50 /* [JCH-96/01/21] Extended std reverse map to four buttons. */
52 #ifdef HAVE_XORG_CONFIG_H
53 #include <xorg-config.h>
57 #include <X11/Xpoll.h>
58 #include <X11/Xproto.h>
66 #include "xf86_OSlib.h"
67 #include "atKeynames.h"
75 #include <X11/extensions/XI.h>
76 #include <X11/extensions/XIproto.h>
80 #include "xf86Xinput.h"
83 #include "mipointer.h"
86 #define _XF86BIGFONT_SERVER_
87 #include <X11/extensions/xf86bigfont.h>
91 extern Bool noXkbExtension
;
96 #include <X11/extensions/dpms.h>
101 #define XE_KEYBOARD 2
103 #define EqEnqueue(pDev, ev) { \
104 int __sigstate = xf86BlockSIGIO (); \
105 mieqEnqueue (pDev, ev); \
106 xf86UnblockSIGIO(__sigstate); \
110 * The first of many hacks to get VT switching to work under
111 * Solaris 2.1 for x86. The basic problem is that Solaris is supposed
112 * to be SVR4. It is for the most part, except where the video interface
113 * is concerned. These hacks work around those problems.
114 * See the comments for Linux, and SCO.
116 * This is a toggling variable:
117 * FALSE = No VT switching keys have been pressed last time around
118 * TRUE = Possible VT switch Pending
121 * This has been generalised to work with Linux and *BSD+syscons (DHD)
124 _X_EXPORT Bool VTSwitchEnabled
= TRUE
; /* Allows run-time disabling for
125 *BSD and for avoiding VT
126 switches when using the DRI
127 automatic full screen mode.*/
129 extern fd_set EnabledDevices
;
132 extern void (*xf86OSPMClose
)(void);
135 static void xf86VTSwitch(void);
138 * Allow arbitrary drivers or other XFree86 code to register with our main
141 typedef struct x_IHRec
{
143 InputHandlerProc ihproc
;
146 struct x_IHRec
* next
;
149 static IHPtr InputHandlers
= NULL
;
153 LegalModifier(unsigned int key
, DeviceIntPtr pDev
)
159 * TimeSinceLastInputEvent --
160 * Function used for screensaver purposes by the os module. Returns the
161 * time in milliseconds since there last was any input.
165 TimeSinceLastInputEvent()
167 if (xf86Info
.lastEventTime
== 0) {
168 xf86Info
.lastEventTime
= GetTimeInMillis();
170 return GetTimeInMillis() - xf86Info
.lastEventTime
;
176 * SetTimeSinceLastInputEvent --
177 * Set the lastEventTime to now.
181 SetTimeSinceLastInputEvent()
183 xf86Info
.lastEventTime
= GetTimeInMillis();
189 * ProcessInputEvents --
190 * Retrieve all waiting input events and pass them to DIX in their
191 * correct chronological order. Only reads from the system pointer
196 ProcessInputEvents ()
199 #ifdef INHERIT_LOCK_STATE
200 static int generation
= 0;
204 * With INHERIT_LOCK_STATE defined, the initial state of CapsLock, NumLock
205 * and ScrollLock will be set to match that of the VT the server is
208 #ifdef INHERIT_LOCK_STATE
209 if (generation
!= serverGeneration
) {
211 DevicePtr pKeyboard
= xf86Info
.pKeyboard
;
212 extern unsigned int xf86InitialCaps
, xf86InitialNum
, xf86InitialScroll
;
214 generation
= serverGeneration
;
215 kevent
.u
.keyButtonPointer
.time
= GetTimeInMillis();
216 kevent
.u
.keyButtonPointer
.rootX
= 0;
217 kevent
.u
.keyButtonPointer
.rootY
= 0;
218 kevent
.u
.u
.type
= KeyPress
;
221 if (xf86InitialCaps
) {
222 kevent
.u
.u
.detail
= xf86InitialCaps
;
223 (* pKeyboard
->processInputProc
)(&kevent
, (DeviceIntPtr
)pKeyboard
, 1);
226 if (xf86InitialNum
) {
227 kevent
.u
.u
.detail
= xf86InitialNum
;
228 (* pKeyboard
->processInputProc
)(&kevent
, (DeviceIntPtr
)pKeyboard
, 1);
231 if (xf86InitialScroll
) {
232 kevent
.u
.u
.detail
= xf86InitialScroll
;
233 (* pKeyboard
->processInputProc
)(&kevent
, (DeviceIntPtr
)pKeyboard
, 1);
234 xf86InitialScroll
= 0;
239 xf86Info
.inputPending
= FALSE
;
241 mieqProcessInputEvents();
242 miPointerUpdateSprite(inputInfo
.pointer
);
244 miPointerGetPosition(inputInfo
.pointer
, &x
, &y
);
245 xf86SetViewport(xf86Info
.currentScreen
, x
, y
);
249 xf86GrabServerCallback(CallbackListPtr
*callbacks
, pointer data
, pointer args
)
251 ServerGrabInfoRec
*grab
= (ServerGrabInfoRec
*)args
;
253 xf86Info
.grabInfo
.server
.client
= grab
->client
;
254 xf86Info
.grabInfo
.server
.grabstate
= grab
->grabstate
;
258 * Handle keyboard events that cause some kind of "action"
259 * (i.e., server termination, video mode changes, VT switches, etc.)
262 xf86ProcessActionEvent(ActionEvent action
, void *arg
)
265 ErrorF("ProcessActionEvent(%d,%x)\n", (int) action
, arg
);
268 case ACTION_TERMINATE
:
269 if (!xf86Info
.dontZap
) {
276 case ACTION_NEXT_MODE
:
277 if (!xf86Info
.dontZoom
)
278 xf86ZoomViewport(xf86Info
.currentScreen
, 1);
280 case ACTION_PREV_MODE
:
281 if (!xf86Info
.dontZoom
)
282 xf86ZoomViewport(xf86Info
.currentScreen
, -1);
284 case ACTION_DISABLEGRAB
:
285 if (!xf86Info
.grabInfo
.disabled
&& xf86Info
.grabInfo
.allowDeactivate
) {
286 if (inputInfo
.pointer
&& inputInfo
.pointer
->grab
!= NULL
&&
287 inputInfo
.pointer
->DeactivateGrab
)
288 inputInfo
.pointer
->DeactivateGrab(inputInfo
.pointer
);
289 if (inputInfo
.keyboard
&& inputInfo
.keyboard
->grab
!= NULL
&&
290 inputInfo
.keyboard
->DeactivateGrab
)
291 inputInfo
.keyboard
->DeactivateGrab(inputInfo
.keyboard
);
294 case ACTION_CLOSECLIENT
:
295 if (!xf86Info
.grabInfo
.disabled
&& xf86Info
.grabInfo
.allowClosedown
) {
296 ClientPtr pointer
, keyboard
, server
;
298 pointer
= keyboard
= server
= NULL
;
299 if (inputInfo
.pointer
&& inputInfo
.pointer
->grab
!= NULL
)
300 pointer
= clients
[CLIENT_ID(inputInfo
.pointer
->grab
->resource
)];
301 if (inputInfo
.keyboard
&& inputInfo
.keyboard
->grab
!= NULL
) {
302 keyboard
= clients
[CLIENT_ID(inputInfo
.keyboard
->grab
->resource
)];
303 if (keyboard
== pointer
)
306 if ((xf86Info
.grabInfo
.server
.grabstate
== SERVER_GRABBED
) &&
307 (((server
= xf86Info
.grabInfo
.server
.client
) == pointer
) ||
308 (server
== keyboard
)))
312 CloseDownClient(pointer
);
314 CloseDownClient(keyboard
);
316 CloseDownClient(server
);
319 #if !defined(__SOL8__) && !defined(sgi) && \
320 (!defined(sun) || defined(i386)) && defined(VT_ACTIVATE)
321 case ACTION_SWITCHSCREEN
:
322 if (VTSwitchEnabled
&& !xf86Info
.dontVTSwitch
&& arg
) {
323 int vtno
= *((int *) arg
);
324 #if defined(__SCO__) || defined(__UNIXWARE__)
328 xf86Info
.vtRequestsPending
= vtno
;
330 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, vtno
) < 0)
331 ErrorF("Failed to switch consoles (%s)\n", strerror(errno
));
335 case ACTION_SWITCHSCREEN_NEXT
:
336 if (VTSwitchEnabled
&& !xf86Info
.dontVTSwitch
) {
337 /* Shouldn't this be true for (sun) && (i386) && (SVR4) ? */
338 #if defined(__SCO__) || defined(__UNIXWARE__)
339 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, xf86Info
.vtno
) < 0)
341 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, xf86Info
.vtno
+ 1) < 0)
343 #if defined (__SCO__) || (defined(sun) && defined (i386) && defined (SVR4)) || defined(__UNIXWARE__)
344 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, 0) < 0)
346 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, 1) < 0)
348 ErrorF("Failed to switch consoles (%s)\n", strerror(errno
));
351 case ACTION_SWITCHSCREEN_PREV
:
352 if (VTSwitchEnabled
&& !xf86Info
.dontVTSwitch
&& xf86Info
.vtno
> 0) {
353 if (ioctl(xf86Info
.consoleFd
, VT_ACTIVATE
, xf86Info
.vtno
- 1) < 0)
354 ErrorF("Failed to switch consoles (%s)\n", strerror(errno
));
360 char *retstr
, *message
= (char *) arg
;
361 ScrnInfoPtr pScr
= XF86SCRNINFO(xf86Info
.currentScreen
);
364 ErrorF("ActionMessage: '%s'\n", message
);
366 /* Okay the message made it to the ddx. The common layer */
367 /* can check for relevant messages here and react to any */
368 /* that have a global effect. For example: */
370 /* if (!strcmp(message, "foo") { */
371 /* do_foo(); break */
374 /* otherwise fallback to sending a key event message to */
375 /* the current screen's driver: */
376 if (*pScr
->HandleMessage
!= NULL
) {
377 (void) (*pScr
->HandleMessage
)(pScr
->scrnIndex
,
378 "KeyEventMessage", message
, &retstr
);
387 #define ModifierIsSet(k) ((modifiers & (k)) == (k))
390 xf86CommonSpecialKey(int key
, Bool down
, int modifiers
)
392 if ((!ModifierIsSet(ShiftMask
)) &&
393 (((ModifierIsSet(ControlMask
| AltMask
)) ||
394 (ModifierIsSet(ControlMask
| AltLangMask
))))) {
398 xf86ProcessActionEvent(ACTION_TERMINATE
, NULL
);
405 xf86ProcessActionEvent(ACTION_DISABLEGRAB
, NULL
);
407 case KEY_KP_Multiply
:
408 xf86ProcessActionEvent(ACTION_CLOSECLIENT
, NULL
);
412 * The idea here is to pass the scancode down to a list of
413 * registered routines. There should be some standard conventions
414 * for processing certain keys.
416 case KEY_KP_Minus
: /* Keypad - */
417 if (down
) xf86ProcessActionEvent(ACTION_PREV_MODE
, NULL
);
418 if (!xf86Info
.dontZoom
) return TRUE
;
421 case KEY_KP_Plus
: /* Keypad + */
422 if (down
) xf86ProcessActionEvent(ACTION_NEXT_MODE
, NULL
);
423 if (!xf86Info
.dontZoom
) return TRUE
;
437 xf86Wakeup(pointer blockData
, int err
, pointer pReadmask
)
439 #if !defined(__QNX__)
440 fd_set
* LastSelectMask
= (fd_set
*)pReadmask
;
441 fd_set devicesWithInput
;
446 XFD_ANDSET(&devicesWithInput
, LastSelectMask
, &EnabledDevices
);
447 if (XFD_ANYSET(&devicesWithInput
)) {
448 pInfo
= xf86InputDevs
;
450 if (pInfo
->read_input
&& pInfo
->fd
>= 0 &&
451 (FD_ISSET(pInfo
->fd
, &devicesWithInput
) != 0)) {
452 int sigstate
= xf86BlockSIGIO();
454 pInfo
->read_input(pInfo
);
455 xf86UnblockSIGIO(sigstate
);
457 * Remove the descriptior from the set because more than one
458 * device may share the same file descriptor.
460 FD_CLR(pInfo
->fd
, &devicesWithInput
);
470 pInfo
= xf86InputDevs
;
472 if (pInfo
->read_input
&& pInfo
->fd
>= 0) {
473 int sigstate
= xf86BlockSIGIO();
475 pInfo
->read_input(pInfo
);
476 xf86UnblockSIGIO(sigstate
);
478 * Must break here because more than one device may share
479 * the same file descriptor.
488 if (err
>= 0) { /* we don't want the handlers called if select() */
489 IHPtr ih
; /* returned with an error condition, do we? */
491 for (ih
= InputHandlers
; ih
; ih
= ih
->next
) {
492 if (ih
->enabled
&& ih
->fd
>= 0 && ih
->ihproc
&&
493 (FD_ISSET(ih
->fd
, ((fd_set
*)pReadmask
)) != 0)) {
494 ih
->ihproc(ih
->fd
, ih
->data
);
499 if (xf86VTSwitchPending()) xf86VTSwitch();
501 if (xf86Info
.inputPending
) ProcessInputEvents();
506 * xf86SigioReadInput --
507 * signal handler for the SIGIO signal.
510 xf86SigioReadInput(int fd
,
513 int sigstate
= xf86BlockSIGIO();
514 InputInfoPtr pInfo
= (InputInfoPtr
) closure
;
516 pInfo
->read_input(pInfo
);
518 xf86UnblockSIGIO(sigstate
);
522 * xf86AddEnabledDevice --
526 xf86AddEnabledDevice(InputInfoPtr pInfo
)
528 if (!xf86InstallSIGIOHandler (pInfo
->fd
, xf86SigioReadInput
, pInfo
)) {
529 AddEnabledDevice(pInfo
->fd
);
534 * xf86RemoveEnabledDevice --
538 xf86RemoveEnabledDevice(InputInfoPtr pInfo
)
540 if (!xf86RemoveSIGIOHandler (pInfo
->fd
)) {
541 RemoveEnabledDevice(pInfo
->fd
);
545 static int *xf86SignalIntercept
= NULL
;
548 xf86InterceptSignals(int *signo
)
550 if ((xf86SignalIntercept
= signo
))
554 static void (*xf86SigIllHandler
)(void) = NULL
;
557 xf86InterceptSigIll(void (*sigillhandler
)(void))
559 xf86SigIllHandler
= sigillhandler
;
562 #ifdef HAVE_BACKTRACE
563 #include <execinfo.h>
565 static __inline__
void xorg_backtrace(void)
567 void *array
[32]; /* deeper nesting than this means something's wrong */
570 ErrorF("\nBacktrace:\n");
571 size
= backtrace(array
, 32);
572 strings
= backtrace_symbols(array
, size
);
573 for (i
= 0; i
< size
; i
++)
574 ErrorF("%d: %s\n", i
, strings
[i
]);
578 #else /* not glibc or glibc < 2.1 */
580 # if defined(sun) && defined(__SVR4)
584 # if defined(HAVE_WALKCONTEXT) /* Solaris 9 & later */
586 # include <ucontext.h>
589 # include <sys/elf.h>
592 # define ElfSym Elf64_Sym
594 # define ElfSym Elf32_Sym
597 /* Called for each frame on the stack to print it's contents */
598 static int xorg_backtrace_frame(uintptr_t pc
, int signo
, void *arg
)
603 int depth
= *((int *) arg
);
606 char signame
[SIG2STR_MAX
];
608 if (sig2str(signo
, signame
) != 0) {
609 strcpy(signame
, "unknown");
612 ErrorF("** Signal %d (%s)\n", signo
, signame
);
615 snprintf(header
, sizeof(header
), "%d: 0x%lx", depth
, pc
);
616 *((int *) arg
) = depth
+ 1;
618 /* Ask system dynamic loader for info on the address */
619 if (dladdr1((void *) pc
, &dlinfo
, (void **) &dlsym
, RTLD_DL_SYMENT
)) {
620 unsigned long offset
= pc
- (uintptr_t) dlinfo
.dli_saddr
;
623 if (offset
< dlsym
->st_size
) { /* inside a function */
624 symname
= dlinfo
.dli_sname
;
625 } else { /* found which file it was in, but not which function */
626 symname
= "<section start>";
627 offset
= pc
- (uintptr_t)dlinfo
.dli_fbase
;
629 ErrorF("%s: %s:%s+0x%lx\n", header
, dlinfo
.dli_fname
,
633 /* Couldn't find symbol info from system dynamic loader, should
634 * probably poke elfloader here, but haven't written that code yet,
635 * so we just print the pc.
637 ErrorF("%s\n", header
);
642 # endif /* HAVE_WALKCONTEXT */
645 static int xorg_backtrace_pstack(void) {
649 if (pipe(pipefd
) != 0) {
658 } else if (kidpid
== 0) {
664 close(STDOUT_FILENO
);
665 dup2(pipefd
[1],STDOUT_FILENO
);
666 closefrom(STDERR_FILENO
);
668 snprintf(parent
, sizeof(parent
), "%d", getppid());
669 execle("/usr/bin/pstack", "pstack", parent
, NULL
);
681 bytesread
= read(pipefd
[0], btline
, sizeof(btline
) - 1);
684 btline
[bytesread
] = 0;
685 ErrorF("%s", btline
);
687 else if ((bytesread
< 0) ||
688 ((errno
!= EINTR
) && (errno
!= EAGAIN
)))
692 waitpid(kidpid
, &kidstat
, 0);
698 # endif /* HAVE_PSTACK */
701 # if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
703 static __inline__
void xorg_backtrace(void) {
705 ErrorF("\nBacktrace:\n");
708 /* First try fork/exec of pstack - otherwise fall back to walkcontext
709 pstack is preferred since it can print names of non-exported functions */
711 if (xorg_backtrace_pstack() < 0)
714 # ifdef HAVE_WALKCONTEXT
718 if (getcontext(&u
) == 0)
719 walkcontext(&u
, xorg_backtrace_frame
, &depth
);
722 Error("Failed to get backtrace info");
729 /* Default fallback if we can't find any way to get a backtrace */
730 static __inline__
void xorg_backtrace(void) { return; }
737 * Catch unexpected signals and exit or continue cleanly.
740 xf86SigHandler(int signo
)
742 if ((signo
== SIGILL
) && xf86SigIllHandler
) {
743 (*xf86SigIllHandler
)();
744 /* Re-arm handler just in case we unexpectedly return here */
745 (void) signal(signo
, xf86SigHandler
);
749 if (xf86SignalIntercept
&& (*xf86SignalIntercept
< 0)) {
750 *xf86SignalIntercept
= signo
;
751 /* Re-arm handler just in case */
752 (void) signal(signo
, xf86SigHandler
);
756 signal(signo
,SIG_IGN
);
757 xf86Info
.caughtSignal
= TRUE
;
759 XF86BigfontCleanup();
764 FatalError("Caught signal %d. Server aborting\n", signo
);
768 xf86ReleaseKeys(DeviceIntPtr pDev
)
770 KeyClassPtr keyc
= NULL
;
773 int i
= 0, j
= 0, nevents
= 0;
775 if (!pDev
|| !pDev
->key
)
779 map
= keyc
->curKeySyms
.map
;
782 * Hmm... here is the biggest hack of every time !
783 * It may be possible that a switch-vt procedure has finished BEFORE
784 * you released all keys neccessary to do this. That peculiar behavior
785 * can fool the X-server pretty much, cause it assumes that some keys
786 * were not released. TWM may stuck alsmost completly....
787 * OK, what we are doing here is after returning from the vt-switch
788 * exeplicitely unrelease all keyboard keys before the input-devices
792 for (i
= keyc
->curKeySyms
.minKeyCode
, map
= keyc
->curKeySyms
.map
;
793 i
< keyc
->curKeySyms
.maxKeyCode
;
794 i
++, map
+= keyc
->curKeySyms
.mapWidth
) {
797 /* Don't release the lock keys */
805 if (pDev
== inputInfo
.keyboard
) {
806 ke
.u
.keyButtonPointer
.time
= GetTimeInMillis();
807 ke
.u
.keyButtonPointer
.rootX
= 0;
808 ke
.u
.keyButtonPointer
.rootY
= 0;
809 ke
.u
.u
.type
= KeyRelease
;
811 (*pDev
->public.processInputProc
) (&ke
, pDev
, 1);
814 int sigstate
= xf86BlockSIGIO ();
815 nevents
= GetKeyboardEvents(xf86Events
, pDev
, KeyRelease
, i
);
816 for (j
= 0; j
< nevents
; j
++)
817 mieqEnqueue(pDev
, xf86Events
+ j
);
818 xf86UnblockSIGIO(sigstate
);
828 * Handle requests for switching the vt.
838 ErrorF("xf86VTSwitch()\n");
847 * Since all screens are currently all in the same state it is sufficient
848 * check the first. This might change in future.
850 if (xf86Screens
[0]->vtSema
) {
853 ErrorF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
854 BOOLTOSTRING((dispatchException
& DE_TERMINATE
) ? TRUE
: FALSE
));
857 if (DPMSPowerLevel
!= DPMSModeOn
)
860 for (i
= 0; i
< xf86NumScreens
; i
++) {
861 if (!(dispatchException
& DE_TERMINATE
))
862 if (xf86Screens
[i
]->EnableDisableFBAccess
)
863 (*xf86Screens
[i
]->EnableDisableFBAccess
) (i
, FALSE
);
867 * Keep the order: Disable Device > LeaveVT
868 * EnterVT > EnableDevice
870 pInfo
= xf86InputDevs
;
873 DisableDevice(pInfo
->dev
);
876 xf86EnterServerState(SETUP
);
877 for (i
= 0; i
< xf86NumScreens
; i
++)
878 xf86Screens
[i
]->LeaveVT(i
, 0);
880 for (ih
= InputHandlers
; ih
; ih
= ih
->next
)
881 xf86DisableInputHandler(ih
);
882 xf86AccessLeave(); /* We need this here, otherwise */
883 xf86AccessLeaveState(); /* console won't be restored */
885 if (!xf86VTSwitchAway()) {
891 ErrorF("xf86VTSwitch: Leave failed\n");
893 prevSIGIO
= xf86BlockSIGIO();
895 xf86EnterServerState(SETUP
);
896 for (i
= 0; i
< xf86NumScreens
; i
++) {
897 if (!xf86Screens
[i
]->EnterVT(i
, 0))
898 FatalError("EnterVT failed for screen %d\n", i
);
900 xf86EnterServerState(OPERATING
);
901 if (!(dispatchException
& DE_TERMINATE
)) {
902 for (i
= 0; i
< xf86NumScreens
; i
++) {
903 if (xf86Screens
[i
]->EnableDisableFBAccess
)
904 (*xf86Screens
[i
]->EnableDisableFBAccess
) (i
, TRUE
);
907 SaveScreens(SCREEN_SAVER_FORCER
, ScreenSaverReset
);
909 pInfo
= xf86InputDevs
;
912 xf86ReleaseKeys(pInfo
->dev
);
913 EnableDevice(pInfo
->dev
);
918 xf86ReleaseKeys(inputInfo
.keyboard
);
919 for (ih
= InputHandlers
; ih
; ih
= ih
->next
)
920 xf86EnableInputHandler(ih
);
922 xf86UnblockSIGIO(prevSIGIO
);
928 xf86OSPMClose
= NULL
;
931 for (i
= 0; i
< xf86NumScreens
; i
++) {
933 * zero all access functions to
934 * trap calls when switched away.
936 xf86Screens
[i
]->vtSema
= FALSE
;
937 xf86Screens
[i
]->access
= NULL
;
938 xf86Screens
[i
]->busAccess
= NULL
;
946 ErrorF("xf86VTSwitch: Entering\n");
948 if (!xf86VTSwitchTo()) return;
950 prevSIGIO
= xf86BlockSIGIO();
952 xf86OSPMClose
= xf86OSPMOpen();
958 xf86EnterServerState(SETUP
);
959 for (i
= 0; i
< xf86NumScreens
; i
++) {
960 xf86Screens
[i
]->vtSema
= TRUE
;
961 if (!xf86Screens
[i
]->EnterVT(i
, 0))
962 FatalError("EnterVT failed for screen %d\n", i
);
964 xf86EnterServerState(OPERATING
);
965 for (i
= 0; i
< xf86NumScreens
; i
++) {
966 if (xf86Screens
[i
]->EnableDisableFBAccess
)
967 (*xf86Screens
[i
]->EnableDisableFBAccess
)(i
, TRUE
);
970 /* Turn screen saver off when switching back */
971 SaveScreens(SCREEN_SAVER_FORCER
,ScreenSaverReset
);
973 pInfo
= xf86InputDevs
;
976 xf86ReleaseKeys(pInfo
->dev
);
977 EnableDevice(pInfo
->dev
);
982 xf86ReleaseKeys(inputInfo
.keyboard
);
984 for (ih
= InputHandlers
; ih
; ih
= ih
->next
)
985 xf86EnableInputHandler(ih
);
987 xf86UnblockSIGIO(prevSIGIO
);
992 /* Input handler registration */
995 addInputHandler(int fd
, InputHandlerProc proc
, pointer data
)
1002 ih
= xcalloc(sizeof(*ih
), 1);
1011 ih
->next
= InputHandlers
;
1018 xf86AddInputHandler(int fd
, InputHandlerProc proc
, pointer data
)
1020 IHPtr ih
= addInputHandler(fd
, proc
, data
);
1023 AddEnabledDevice(fd
);
1028 xf86AddGeneralHandler(int fd
, InputHandlerProc proc
, pointer data
)
1030 IHPtr ih
= addInputHandler(fd
, proc
, data
);
1033 AddGeneralSocket(fd
);
1038 removeInputHandler(IHPtr ih
)
1042 if (ih
== InputHandlers
)
1043 InputHandlers
= ih
->next
;
1046 while (p
&& p
->next
!= ih
)
1055 xf86RemoveInputHandler(pointer handler
)
1067 RemoveEnabledDevice(ih
->fd
);
1068 removeInputHandler(ih
);
1074 xf86RemoveGeneralHandler(pointer handler
)
1086 RemoveGeneralSocket(ih
->fd
);
1087 removeInputHandler(ih
);
1093 xf86DisableInputHandler(pointer handler
)
1101 ih
->enabled
= FALSE
;
1103 RemoveEnabledDevice(ih
->fd
);
1107 xf86DisableGeneralHandler(pointer handler
)
1115 ih
->enabled
= FALSE
;
1117 RemoveGeneralSocket(ih
->fd
);
1121 xf86EnableInputHandler(pointer handler
)
1131 AddEnabledDevice(ih
->fd
);
1135 xf86EnableGeneralHandler(pointer handler
)
1145 AddGeneralSocket(ih
->fd
);
1149 * As used currently by the DRI, the return value is ignored.
1152 xf86EnableVTSwitch(Bool
new)
1154 static Bool def
= TRUE
;
1157 old
= VTSwitchEnabled
;
1159 /* Disable VT switching */
1160 def
= VTSwitchEnabled
;
1161 VTSwitchEnabled
= FALSE
;
1163 /* Restore VT switching to default */
1164 VTSwitchEnabled
= def
;
1170 xf86ReloadInputDevs(int sig
)
1174 signal(sig
, (void(*)(int))xf86ReloadInputDevs
);
1176 pInfo
= xf86InputDevs
;
1178 DisableDevice(pInfo
->dev
);
1179 EnableDevice(pInfo
->dev
);
1180 pInfo
= pInfo
->next
;
1187 DDXRingBell(int volume
, int pitch
, int duration
) {
1188 xf86OSRingBell(volume
, pitch
, duration
);