1788 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1788 lines
		
	
	
		
			47 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of Thomas Roell not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Thomas Roell makes no representations
 | |
|  * about the suitability of this software for any purpose.  It is provided
 | |
|  * "as is" without express or implied warranty.
 | |
|  *
 | |
|  * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | |
|  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | |
|  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
|  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
|  * PERFORMANCE OF THIS SOFTWARE.
 | |
|  *
 | |
|  */
 | |
| /*
 | |
|  * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
 | |
|  *
 | |
|  * Permission is hereby granted, free of charge, to any person obtaining a
 | |
|  * copy of this software and associated documentation files (the "Software"),
 | |
|  * to deal in the Software without restriction, including without limitation
 | |
|  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 | |
|  * and/or sell copies of the Software, and to permit persons to whom the
 | |
|  * Software is furnished to do so, subject to the following conditions:
 | |
|  *
 | |
|  * The above copyright notice and this permission notice shall be included in
 | |
|  * all copies or substantial portions of the Software.
 | |
|  *
 | |
|  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
|  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
|  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 | |
|  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | |
|  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 | |
|  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 | |
|  * OTHER DEALINGS IN THE SOFTWARE.
 | |
|  *
 | |
|  * Except as contained in this notice, the name of the copyright holder(s)
 | |
|  * and author(s) shall not be used in advertising or otherwise to promote
 | |
|  * the sale, use or other dealings in this Software without prior written
 | |
|  * authorization from the copyright holder(s) and author(s).
 | |
|  */
 | |
| 
 | |
| /* [JCH-96/01/21] Extended std reverse map to four buttons. */
 | |
| 
 | |
| #ifdef HAVE_XORG_CONFIG_H
 | |
| #include <xorg-config.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef __UNIXOS2__
 | |
| #define I_NEED_OS2_H
 | |
| #endif
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xpoll.h>
 | |
| #include <X11/Xproto.h>
 | |
| #include "misc.h"
 | |
| 
 | |
| #include "compiler.h"
 | |
| 
 | |
| #include "xf86.h"
 | |
| #include "xf86Priv.h"
 | |
| #define XF86_OS_PRIVS
 | |
| #include "xf86_OSlib.h"
 | |
| #include "atKeynames.h"
 | |
| 
 | |
| 
 | |
| #ifdef XFreeXDGA
 | |
| #include "dgaproc.h"
 | |
| #endif
 | |
| 
 | |
| #ifdef XINPUT
 | |
| #include <X11/extensions/XI.h>
 | |
| #include <X11/extensions/XIproto.h>
 | |
| #else
 | |
| #include "inputstr.h"
 | |
| #endif
 | |
| #include "xf86Xinput.h"
 | |
| 
 | |
| #include "mi.h"
 | |
| #include "mipointer.h"
 | |
| 
 | |
| #ifdef XF86BIGFONT
 | |
| #define _XF86BIGFONT_SERVER_
 | |
| #include <X11/extensions/xf86bigfont.h>
 | |
| #endif
 | |
| 
 | |
| #ifdef XKB
 | |
| extern Bool noXkbExtension;
 | |
| #endif
 | |
| 
 | |
| #ifdef DPMSExtension
 | |
| #define DPMS_SERVER
 | |
| #include <X11/extensions/dpms.h>
 | |
| #include "dpmsproc.h"
 | |
| #endif
 | |
| 
 | |
| #define XE_POINTER  1
 | |
| #define XE_KEYBOARD 2
 | |
| 
 | |
| #ifdef XINPUT
 | |
| #define __EqEnqueue(ev) xf86eqEnqueue(ev)
 | |
| #else
 | |
| #define __EqEnqueue(ev) mieqEnqueue(ev)
 | |
| #endif
 | |
| 
 | |
| #define EqEnqueue(ev) { \
 | |
|     int __sigstate = xf86BlockSIGIO (); \
 | |
|     __EqEnqueue (ev); \
 | |
|     xf86UnblockSIGIO(__sigstate); \
 | |
| }
 | |
| 
 | |
| #define ENQUEUE(ev, code, direction, dev_type) \
 | |
|   (ev)->u.u.detail = (code); \
 | |
|   (ev)->u.u.type   = (direction); \
 | |
|   EqEnqueue((ev))
 | |
| 
 | |
| /*
 | |
|  * The first of many hacks to get VT switching to work under
 | |
|  * Solaris 2.1 for x86. The basic problem is that Solaris is supposed
 | |
|  * to be SVR4. It is for the most part, except where the video interface
 | |
|  * is concerned.  These hacks work around those problems.
 | |
|  * See the comments for Linux, and SCO.
 | |
|  *
 | |
|  * This is a toggling variable:
 | |
|  *  FALSE = No VT switching keys have been pressed last time around
 | |
|  *  TRUE  = Possible VT switch Pending
 | |
|  * (DWH - 12/2/93)
 | |
|  *
 | |
|  * This has been generalised to work with Linux and *BSD+syscons (DHD)
 | |
|  */
 | |
| 
 | |
| #ifdef USE_VT_SYSREQ
 | |
| Bool VTSysreqToggle = FALSE;
 | |
| #endif /* !USE_VT_SYSREQ */
 | |
| Bool VTSwitchEnabled = TRUE;		/* Allows run-time disabling for
 | |
|                                          *BSD and for avoiding VT
 | |
|                                          switches when using the DRI
 | |
|                                          automatic full screen mode.*/
 | |
| 
 | |
| extern fd_set EnabledDevices;
 | |
| 
 | |
| #if defined(XQUEUE)
 | |
| extern void xf86XqueRequest(void);
 | |
| #endif
 | |
| #ifdef XF86PM
 | |
| extern void (*xf86OSPMClose)(void);
 | |
| #endif
 | |
| 
 | |
| static void xf86VTSwitch(void);
 | |
| 
 | |
| /*
 | |
|  * Allow arbitrary drivers or other XFree86 code to register with our main
 | |
|  * Wakeup handler.
 | |
|  */
 | |
| typedef struct x_IHRec {
 | |
|     int			fd;
 | |
|     InputHandlerProc	ihproc;
 | |
|     pointer		data;
 | |
|     Bool		enabled;
 | |
|     struct x_IHRec *	next;
 | |
| } IHRec, *IHPtr;
 | |
| 
 | |
| static IHPtr InputHandlers = NULL;
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * TimeSinceLastInputEvent --
 | |
|  *      Function used for screensaver purposes by the os module. Returns the
 | |
|  *      time in milliseconds since there last was any input.
 | |
|  */
 | |
| 
 | |
| int
 | |
| TimeSinceLastInputEvent()
 | |
| {
 | |
|   if (xf86Info.lastEventTime == 0) {
 | |
|     xf86Info.lastEventTime = GetTimeInMillis();
 | |
|   }
 | |
|   return GetTimeInMillis() - xf86Info.lastEventTime;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * SetTimeSinceLastInputEvent --
 | |
|  *      Set the lastEventTime to now.
 | |
|  */
 | |
| 
 | |
| _X_EXPORT void
 | |
| SetTimeSinceLastInputEvent()
 | |
| {
 | |
|   xf86Info.lastEventTime = GetTimeInMillis();
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * ProcessInputEvents --
 | |
|  *      Retrieve all waiting input events and pass them to DIX in their
 | |
|  *      correct chronological order. Only reads from the system pointer
 | |
|  *      and keyboard.
 | |
|  */
 | |
| 
 | |
| void
 | |
| ProcessInputEvents ()
 | |
| {
 | |
|   int x, y;
 | |
| #ifdef INHERIT_LOCK_STATE
 | |
|   static int generation = 0;
 | |
| #endif
 | |
| 
 | |
|     /*
 | |
|      * With INHERIT_LOCK_STATE defined, the initial state of CapsLock, NumLock
 | |
|      * and ScrollLock will be set to match that of the VT the server is
 | |
|      * running on.
 | |
|      */
 | |
| #ifdef INHERIT_LOCK_STATE
 | |
|     if (generation != serverGeneration) {
 | |
|       xEvent kevent;
 | |
|       DevicePtr pKeyboard = xf86Info.pKeyboard;
 | |
|       extern unsigned int xf86InitialCaps, xf86InitialNum, xf86InitialScroll;
 | |
| 
 | |
|       generation = serverGeneration;
 | |
|       kevent.u.keyButtonPointer.time = GetTimeInMillis();
 | |
|       kevent.u.keyButtonPointer.rootX = 0;
 | |
|       kevent.u.keyButtonPointer.rootY = 0;
 | |
|       kevent.u.u.type = KeyPress;
 | |
| 
 | |
| 
 | |
|       if (xf86InitialCaps) {
 | |
|         kevent.u.u.detail = xf86InitialCaps;
 | |
|         (* pKeyboard->processInputProc)(&kevent, (DeviceIntPtr)pKeyboard, 1);
 | |
|         xf86InitialCaps = 0;
 | |
|       }
 | |
|       if (xf86InitialNum) {
 | |
|         kevent.u.u.detail = xf86InitialNum;
 | |
|         (* pKeyboard->processInputProc)(&kevent, (DeviceIntPtr)pKeyboard, 1);
 | |
|         xf86InitialNum = 0;
 | |
|       }
 | |
|       if (xf86InitialScroll) {
 | |
|         kevent.u.u.detail = xf86InitialScroll;
 | |
|         (* pKeyboard->processInputProc)(&kevent, (DeviceIntPtr)pKeyboard, 1);
 | |
|         xf86InitialScroll = 0;
 | |
|       }
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|   xf86Info.inputPending = FALSE;
 | |
| 
 | |
| #ifdef XINPUT
 | |
|   xf86eqProcessInputEvents();
 | |
| #else
 | |
|   mieqProcessInputEvents();
 | |
| #endif
 | |
|   miPointerUpdate();
 | |
| 
 | |
|   miPointerPosition(&x, &y);
 | |
|   xf86SetViewport(xf86Info.currentScreen, x, y);
 | |
| }
 | |
| 
 | |
| void
 | |
| xf86GrabServerCallback(CallbackListPtr *callbacks, pointer data, pointer args)
 | |
| {
 | |
|     ServerGrabInfoRec *grab = (ServerGrabInfoRec*)args;
 | |
| 
 | |
|     xf86Info.grabInfo.server.client = grab->client;
 | |
|     xf86Info.grabInfo.server.grabstate = grab->grabstate;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Handle keyboard events that cause some kind of "action"
 | |
|  * (i.e., server termination, video mode changes, VT switches, etc.)
 | |
|  */
 | |
| void
 | |
| xf86ProcessActionEvent(ActionEvent action, void *arg)
 | |
| {
 | |
| #ifdef DEBUG
 | |
|     ErrorF("ProcessActionEvent(%d,%x)\n", (int) action, arg);
 | |
| #endif
 | |
|     switch (action) {
 | |
|     case ACTION_TERMINATE:
 | |
| 	if (!xf86Info.dontZap) {
 | |
| #ifdef XFreeXDGA
 | |
| 	    DGAShutdown();
 | |
| #endif
 | |
| 	    GiveUp(0);
 | |
| 	}
 | |
| 	break;
 | |
|     case ACTION_NEXT_MODE:
 | |
| 	if (!xf86Info.dontZoom)
 | |
| 	    xf86ZoomViewport(xf86Info.currentScreen,  1);
 | |
| 	break;
 | |
|     case ACTION_PREV_MODE:
 | |
| 	if (!xf86Info.dontZoom)
 | |
| 	    xf86ZoomViewport(xf86Info.currentScreen, -1);
 | |
| 	break;
 | |
|     case ACTION_DISABLEGRAB:
 | |
| 	if (!xf86Info.grabInfo.disabled && xf86Info.grabInfo.allowDeactivate) {
 | |
| 	  if (inputInfo.pointer && inputInfo.pointer->grab != NULL &&
 | |
| 	      inputInfo.pointer->DeactivateGrab)
 | |
| 	    inputInfo.pointer->DeactivateGrab(inputInfo.pointer);
 | |
| 	  if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL &&
 | |
| 	      inputInfo.keyboard->DeactivateGrab)
 | |
| 	    inputInfo.keyboard->DeactivateGrab(inputInfo.keyboard);
 | |
| 	}
 | |
| 	break;
 | |
|     case ACTION_CLOSECLIENT:
 | |
| 	if (!xf86Info.grabInfo.disabled && xf86Info.grabInfo.allowClosedown) {
 | |
| 	  ClientPtr pointer, keyboard, server;
 | |
| 
 | |
| 	  pointer = keyboard = server = NULL;
 | |
| 	  if (inputInfo.pointer && inputInfo.pointer->grab != NULL)
 | |
| 	    pointer = clients[CLIENT_ID(inputInfo.pointer->grab->resource)];
 | |
| 	  if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL) {
 | |
| 	    keyboard = clients[CLIENT_ID(inputInfo.keyboard->grab->resource)];
 | |
| 	    if (keyboard == pointer)
 | |
| 	      keyboard = NULL;
 | |
| 	  }
 | |
| 	  if ((xf86Info.grabInfo.server.grabstate == SERVER_GRABBED) &&
 | |
| 	      (((server = xf86Info.grabInfo.server.client) == pointer) ||
 | |
| 	       (server == keyboard)))
 | |
| 	      server = NULL;
 | |
| 
 | |
| 	  if (pointer)
 | |
| 	    CloseDownClient(pointer);
 | |
| 	  if (keyboard)
 | |
| 	    CloseDownClient(keyboard);
 | |
| 	  if (server)
 | |
| 	    CloseDownClient(server);
 | |
| 	}
 | |
| 	break;
 | |
| #if !defined(__SOL8__) && !defined(__UNIXOS2__) && !defined(sgi) && \
 | |
|     (!defined(sun) || defined(i386)) && defined(VT_ACTIVATE)
 | |
|     case ACTION_SWITCHSCREEN:
 | |
| 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch && arg) {
 | |
| 	    int vtno = *((int *) arg);
 | |
| #if defined(__SCO__) || defined(__UNIXWARE__)
 | |
| 	    vtno--;
 | |
| #endif
 | |
| #if defined(QNX4)
 | |
| 	    xf86Info.vtRequestsPending = vtno;
 | |
| #else
 | |
| 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, vtno) < 0)
 | |
| 		ErrorF("Failed to switch consoles (%s)\n", strerror(errno));
 | |
| #endif
 | |
| 	}
 | |
| 	break;
 | |
|     case ACTION_SWITCHSCREEN_NEXT:
 | |
| 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch) {
 | |
| /* Shouldn't this be true for (sun) && (i386) && (SVR4) ? */
 | |
| #if defined(__SCO__) || defined(__UNIXWARE__)
 | |
| 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno) < 0)
 | |
| #else
 | |
| 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno + 1) < 0)
 | |
| #endif
 | |
| #if defined (__SCO__) || (defined(sun) && defined (i386) && defined (SVR4)) || defined(__UNIXWARE__)
 | |
| 		if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 0) < 0)
 | |
| #else
 | |
| 		if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, 1) < 0)
 | |
| #endif
 | |
| 		    ErrorF("Failed to switch consoles (%s)\n", strerror(errno));
 | |
| 	}
 | |
| 	break;
 | |
|     case ACTION_SWITCHSCREEN_PREV:
 | |
| 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch && xf86Info.vtno > 0) {
 | |
| 	    if (ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86Info.vtno - 1) < 0)
 | |
| 		ErrorF("Failed to switch consoles (%s)\n", strerror(errno));
 | |
| 	}
 | |
| 	break;
 | |
| #endif
 | |
|     case ACTION_MESSAGE:
 | |
|         {
 | |
|             char *retstr, *message = (char *) arg;
 | |
| 	    ScrnInfoPtr pScr = XF86SCRNINFO(xf86Info.currentScreen);
 | |
| 
 | |
| #ifdef DEBUG
 | |
|             ErrorF("ActionMessage: '%s'\n", message);
 | |
| #endif
 | |
| 	    /* Okay the message made it to the ddx.  The common layer */
 | |
| 	    /* can check for relevant messages here and react to any  */
 | |
| 	    /* that have a global effect.  For example:               */ 
 | |
| 	    /*                                                        */
 | |
| 	    /* if (!strcmp(message, "foo") {                          */
 | |
| 	    /*      do_foo(); break                                   */
 | |
| 	    /* }                                                      */
 | |
| 	    /*                                                        */
 | |
| 	    /* otherwise fallback to sending a key event message to   */
 | |
| 	    /* the current screen's driver:                           */
 | |
| 	    if (*pScr->HandleMessage != NULL) {
 | |
| 		(void) (*pScr->HandleMessage)(pScr->scrnIndex,
 | |
| 			"KeyEventMessage", message, &retstr);
 | |
| 	    }
 | |
|         }
 | |
| 	break;
 | |
|     default:
 | |
| 	break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * xf86PostKbdEvent --
 | |
|  *	Translate the raw hardware KbdEvent into an XEvent, and tell DIX
 | |
|  *	about it. Scancode preprocessing and so on is done ...
 | |
|  *
 | |
|  *  OS/2 specific xf86PostKbdEvent(key) has been moved to os-support/os2/os2_kbd.c
 | |
|  *  as some things differ, and I did not want to scatter this routine with
 | |
|  *  ifdefs further (hv).
 | |
|  */
 | |
| 
 | |
| #ifdef __linux__
 | |
| extern u_char SpecialServerMap[];
 | |
| #endif
 | |
| 
 | |
| #if !defined(__UNIXOS2__)
 | |
| void
 | |
| xf86PostKbdEvent(unsigned key)
 | |
| {
 | |
|   int         scanCode = (key & 0x7f);
 | |
|   int         specialkey = 0;
 | |
|   Bool        down = (key & 0x80 ? FALSE : TRUE);
 | |
|   KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key;
 | |
|   Bool        updateLeds = FALSE;
 | |
|   Bool        UsePrefix = FALSE;
 | |
|   Bool        Direction = FALSE;
 | |
|   xEvent      kevent;
 | |
|   KeySym      *keysym;
 | |
|   int         keycode;
 | |
|   static int  lockkeys = 0;
 | |
| #if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
 | |
|   static Bool first_time = TRUE;
 | |
| #endif
 | |
| #if defined(__sparc__) && defined(__linux__)
 | |
|   static int  kbdSun = -1;
 | |
| #endif
 | |
|   /* Disable any keyboard processing while in suspend */
 | |
|   if (xf86inSuspend)
 | |
|       return;
 | |
| 
 | |
| #if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
 | |
|   if (first_time)
 | |
|   {
 | |
|     first_time = FALSE;
 | |
|     VTSwitchEnabled = (xf86Info.consType == SYSCONS)
 | |
| 	    || (xf86Info.consType == PCVT);
 | |
|   }
 | |
| #endif
 | |
| 
 | |
| #if defined (__sparc__) && defined(__linux__)
 | |
|   if (kbdSun == -1) {
 | |
|     if ((xf86Info.xkbmodel && !strcmp(xf86Info.xkbmodel, "sun"))
 | |
| 	|| (xf86Info.xkbrules && !strcmp(xf86Info.xkbrules, "sun")))
 | |
|       kbdSun = 1;
 | |
|     else
 | |
|       kbdSun = 0;
 | |
|   }
 | |
|   if (kbdSun)
 | |
|     goto special;
 | |
| #endif /* __sparc__ && __linux__ */
 | |
| 
 | |
| #ifdef __linux__
 | |
|   if (xf86Info.kbdCustomKeycodes) {
 | |
|     specialkey = SpecialServerMap[scanCode];
 | |
|     goto customkeycodes;
 | |
|   }
 | |
| #endif
 | |
| 
 | |
|   /*
 | |
|    * First do some special scancode remapping ...
 | |
|    */
 | |
|   if (xf86Info.scanPrefix == 0) {
 | |
| 
 | |
|     switch (scanCode) {
 | |
|     case KEY_Prefix0:
 | |
|     case KEY_Prefix1:
 | |
| #if defined(PCCONS_SUPPORT) || defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
 | |
|       if (xf86Info.consType == PCCONS || xf86Info.consType == SYSCONS
 | |
| 	  || xf86Info.consType == PCVT
 | |
| #ifdef WSCONS_SUPPORT
 | |
| 	  || (xf86Info.consType == WSCONS && xf86Info.kbdEvents != xf86WSKbdEvents)
 | |
| #endif
 | |
|       ) {
 | |
| #endif
 | |
|         xf86Info.scanPrefix = scanCode;  /* special prefixes */
 | |
|         return;
 | |
| #if defined(PCCONS_SUPPORT) || defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
 | |
|       }
 | |
|       break;
 | |
| #endif
 | |
|     }
 | |
| #if defined (i386) && defined (SVR4)
 | |
|     /* 
 | |
|      * PANIX returns DICOP standards based keycodes in using 106jp 
 | |
|      * keyboard. We need to remap some keys. 
 | |
|      */
 | |
|     if(xf86Info.panix106 == TRUE){
 | |
|       switch (scanCode) {
 | |
|       case 0x56:        scanCode = KEY_BSlash2;	break;  /* Backslash */
 | |
|       case 0x5A:        scanCode = KEY_NFER;	break;  /* No Kanji Transfer*/
 | |
|       case 0x5B:        scanCode = KEY_XFER;	break;  /* Kanji Tranfer */
 | |
|       case 0x5C:        scanCode = KEY_Yen;	break;  /* Yen curs pgup */
 | |
|       case 0x6B:        scanCode = KEY_Left;	break;  /* Cur Left */
 | |
|       case 0x6F:        scanCode = KEY_PgUp;	break;  /* Cur PageUp */
 | |
|       case 0x72:        scanCode = KEY_AltLang;	break;  /* AltLang(right) */
 | |
|       case 0x73:        scanCode = KEY_RCtrl;	break;  /* not needed */
 | |
|       }
 | |
|     } else
 | |
| #endif /* i386 && SVR4 */
 | |
|     {
 | |
|       switch (scanCode) {
 | |
|       case 0x59:        scanCode = KEY_0x59; break;
 | |
|       case 0x5a:        scanCode = KEY_0x5A; break;
 | |
|       case 0x5b:        scanCode = KEY_0x5B; break;
 | |
|       case 0x5c:        scanCode = KEY_KP_Equal; break; /* Keypad Equal */
 | |
|       case 0x5d:        scanCode = KEY_0x5D; break;
 | |
|       case 0x5e:        scanCode = KEY_0x5E; break;
 | |
|       case 0x5f:        scanCode = KEY_0x5F; break;
 | |
|       case 0x62:        scanCode = KEY_0x62; break;
 | |
|       case 0x63:        scanCode = KEY_0x63; break;
 | |
|       case 0x64:        scanCode = KEY_0x64; break;
 | |
|       case 0x65:        scanCode = KEY_0x65; break;
 | |
|       case 0x66:        scanCode = KEY_0x66; break;
 | |
|       case 0x67:        scanCode = KEY_0x67; break;
 | |
|       case 0x68:        scanCode = KEY_0x68; break;
 | |
|       case 0x69:        scanCode = KEY_0x69; break;
 | |
|       case 0x6a:        scanCode = KEY_0x6A; break;
 | |
|       case 0x6b:        scanCode = KEY_0x6B; break;
 | |
|       case 0x6c:        scanCode = KEY_0x6C; break;
 | |
|       case 0x6d:        scanCode = KEY_0x6D; break;
 | |
|       case 0x6e:        scanCode = KEY_0x6E; break;
 | |
|       case 0x6f:        scanCode = KEY_0x6F; break;
 | |
|       case 0x70:        scanCode = KEY_0x70; break;
 | |
|       case 0x71:        scanCode = KEY_0x71; break;
 | |
|       case 0x72:        scanCode = KEY_0x72; break;
 | |
|       case 0x73:        scanCode = KEY_0x73; break;
 | |
|       case 0x74:        scanCode = KEY_0x74; break;
 | |
|       case 0x75:        scanCode = KEY_0x75; break;
 | |
|       case 0x76:        scanCode = KEY_0x76; break;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   else if (
 | |
| #ifdef CSRG_BASED
 | |
|            (xf86Info.consType == PCCONS || xf86Info.consType == SYSCONS
 | |
| 	    || xf86Info.consType == PCVT
 | |
| #ifdef WSCONS_SUPPORT
 | |
| 	      || (xf86Info.consType == WSCONS && xf86Info.kbdEvents !=
 | |
| 	      xf86WSKbdEvents)
 | |
| #endif
 | |
| 	      ) &&
 | |
| #endif
 | |
|            (xf86Info.scanPrefix == KEY_Prefix0)) {
 | |
|     xf86Info.scanPrefix = 0;
 | |
| 	  
 | |
|     switch (scanCode) {
 | |
|     case KEY_KP_7:        scanCode = KEY_Home;      break;  /* curs home */
 | |
|     case KEY_KP_8:        scanCode = KEY_Up;        break;  /* curs up */
 | |
|     case KEY_KP_9:        scanCode = KEY_PgUp;      break;  /* curs pgup */
 | |
|     case KEY_KP_4:        scanCode = KEY_Left;      break;  /* curs left */
 | |
|     case KEY_KP_5:        scanCode = KEY_Begin;     break;  /* curs begin */
 | |
|     case KEY_KP_6:        scanCode = KEY_Right;     break;  /* curs right */
 | |
|     case KEY_KP_1:        scanCode = KEY_End;       break;  /* curs end */
 | |
|     case KEY_KP_2:        scanCode = KEY_Down;      break;  /* curs down */
 | |
|     case KEY_KP_3:        scanCode = KEY_PgDown;    break;  /* curs pgdown */
 | |
|     case KEY_KP_0:        scanCode = KEY_Insert;    break;  /* curs insert */
 | |
|     case KEY_KP_Decimal:  scanCode = KEY_Delete;    break;  /* curs delete */
 | |
|     case KEY_Enter:       scanCode = KEY_KP_Enter;  break;  /* keypad enter */
 | |
|     case KEY_LCtrl:       scanCode = KEY_RCtrl;     break;  /* right ctrl */
 | |
|     case KEY_KP_Multiply: scanCode = KEY_Print;     break;  /* print */
 | |
|     case KEY_Slash:       scanCode = KEY_KP_Divide; break;  /* keyp divide */
 | |
|     case KEY_Alt:         scanCode = KEY_AltLang;   break;  /* right alt */
 | |
|     case KEY_ScrollLock:  scanCode = KEY_Break;     break;  /* curs break */
 | |
|     case 0x5b:            scanCode = KEY_LMeta;     break;
 | |
|     case 0x5c:            scanCode = KEY_RMeta;     break;
 | |
|     case 0x5d:            scanCode = KEY_Menu;      break;
 | |
|     case KEY_F3:          scanCode = KEY_F13;       break;
 | |
|     case KEY_F4:          scanCode = KEY_F14;       break;
 | |
|     case KEY_F5:          scanCode = KEY_F15;       break;
 | |
|     case KEY_F6:          scanCode = KEY_F16;       break;
 | |
|     case KEY_F7:          scanCode = KEY_F17;       break;
 | |
|     case KEY_KP_Plus:     scanCode = KEY_KP_DEC;    break;
 | |
|       /*
 | |
|        * Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6)
 | |
|        */
 | |
|     case 0x2A:
 | |
|     case 0x36:
 | |
| 	return;
 | |
|     default:
 | |
|       xf86MsgVerb(X_INFO, 4, "Unreported Prefix0 scancode: 0x%02x\n",
 | |
| 		  scanCode);
 | |
|       /*
 | |
|        * "Internet" keyboards are generating lots of new codes.  Let them
 | |
|        * pass.  There is little consistency between them, so don't bother
 | |
|        * with symbolic names at this level.
 | |
|        */
 | |
|       scanCode += 0x78;
 | |
|     }
 | |
|   }
 | |
|   
 | |
|   else if (xf86Info.scanPrefix == KEY_Prefix1)
 | |
|     {
 | |
|       xf86Info.scanPrefix = (scanCode == KEY_LCtrl) ? KEY_LCtrl : 0;
 | |
|       return;
 | |
|     }
 | |
|   
 | |
|   else if (xf86Info.scanPrefix == KEY_LCtrl)
 | |
|     {
 | |
|       xf86Info.scanPrefix = 0;
 | |
|       if (scanCode != KEY_NumLock) return;
 | |
|       scanCode = KEY_Pause;       /* pause */
 | |
|     }
 | |
| 
 | |
| #ifndef __sparc64__
 | |
|   /*
 | |
|    * PC keyboards generate separate key codes for
 | |
|    * Alt+Print and Control+Pause but in the X keyboard model
 | |
|    * they need to get the same key code as the base key on the same
 | |
|    * physical keyboard key.
 | |
|    */
 | |
|   if (scanCode == KEY_SysReqest)
 | |
|     scanCode = KEY_Print;
 | |
|   else if (scanCode == KEY_Break)
 | |
|     scanCode = KEY_Pause;
 | |
| #endif
 | |
|   
 | |
|   /*
 | |
|    * and now get some special keysequences
 | |
|    */
 | |
| 
 | |
|   specialkey = scanCode;
 | |
| 
 | |
| #ifdef __linux__
 | |
| customkeycodes:
 | |
| #endif
 | |
| #if defined(i386) || defined(__i386__)
 | |
|   if (xf86IsPc98()) {
 | |
|     switch (scanCode) {
 | |
|       case 0x0e: specialkey = 0x0e; break; /* KEY_BackSpace */
 | |
|       case 0x40: specialkey = 0x4a; break; /* KEY_KP_Minus  */
 | |
|       case 0x49: specialkey = 0x4e; break; /* KEY_KP_Plus   */
 | |
| 
 | |
|       /* XXX needs cases for KEY_KP_Divide and KEY_KP_Multiply */
 | |
| 
 | |
|       case 0x62: specialkey = 0x3b; break; /* KEY_F1        */
 | |
|       case 0x63: specialkey = 0x3c; break; /* KEY_F2        */
 | |
|       case 0x64: specialkey = 0x3d; break; /* KEY_F3        */
 | |
|       case 0x65: specialkey = 0x3e; break; /* KEY_F4        */
 | |
|       case 0x66: specialkey = 0x3f; break; /* KEY_F5        */
 | |
|       case 0x67: specialkey = 0x40; break; /* KEY_F6        */
 | |
|       case 0x68: specialkey = 0x41; break; /* KEY_F7        */
 | |
|       case 0x69: specialkey = 0x42; break; /* KEY_F8        */
 | |
|       case 0x6a: specialkey = 0x43; break; /* KEY_F9        */
 | |
|       case 0x6b: specialkey = 0x44; break; /* KEY_F10       */
 | |
|       /* case 0x73: specialkey = 0x38; break; KEY_Alt       */
 | |
|       /* case 0x74: specialkey = 0x1d; break; KEY_LCtrl     */
 | |
|       default:   specialkey = 0x00; break;
 | |
|     }
 | |
|   }
 | |
| #endif
 | |
| #if defined (__sparc__) && defined(__linux__)
 | |
| special:
 | |
|   if (kbdSun) {
 | |
|     switch (scanCode) {
 | |
|       case 0x2b: specialkey = KEY_BackSpace; break;
 | |
|       case 0x47: specialkey = KEY_KP_Minus; break;
 | |
|       case 0x7d: specialkey = KEY_KP_Plus; break;
 | |
| 
 | |
|       /* XXX needs cases for KEY_KP_Divide and KEY_KP_Multiply */
 | |
| 
 | |
|       case 0x05: specialkey = KEY_F1; break;
 | |
|       case 0x06: specialkey = KEY_F2; break;
 | |
|       case 0x08: specialkey = KEY_F3; break;
 | |
|       case 0x0a: specialkey = KEY_F4; break;
 | |
|       case 0x0c: specialkey = KEY_F5; break;
 | |
|       case 0x0e: specialkey = KEY_F6; break;
 | |
|       case 0x10: specialkey = KEY_F7; break;
 | |
|       case 0x11: specialkey = KEY_F8; break;
 | |
|       case 0x12: specialkey = KEY_F9; break;
 | |
|       case 0x07: specialkey = KEY_F10; break;
 | |
|       case 0x09: specialkey = KEY_F11; break;
 | |
|       case 0x0b: specialkey = KEY_F12; break;
 | |
|       default: specialkey = 0; break;
 | |
|     }
 | |
|     /*
 | |
|      * XXX XXX XXX:
 | |
|      *
 | |
|      * I really don't know what's wrong here, but passing the real
 | |
|      * scanCode offsets by one from XKB's point of view.
 | |
|      *
 | |
|      * (ecd@skynet.be, 980405)
 | |
|      */
 | |
|     scanCode--;
 | |
|   }
 | |
| #endif /* defined (__sparc__) && defined(__linux__) */
 | |
| 
 | |
| #ifdef XKB
 | |
|   if ((xf86Info.ddxSpecialKeys == SKWhenNeeded &&
 | |
|        !xf86Info.ActionKeyBindingsSet) ||
 | |
|       noXkbExtension || xf86Info.ddxSpecialKeys == SKAlways) {
 | |
| #endif
 | |
|   if (!(ModifierDown(ShiftMask)) &&
 | |
|       ((ModifierDown(ControlMask | AltMask)) ||
 | |
|        (ModifierDown(ControlMask | AltLangMask))))
 | |
|     {
 | |
|       switch (specialkey) {
 | |
| 	
 | |
|       case KEY_BackSpace:
 | |
| 	xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
 | |
| 	break;
 | |
| 
 | |
|       /*
 | |
|        * Check grabs
 | |
|        */
 | |
|       case KEY_KP_Divide:
 | |
| 	xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
 | |
| 	break;
 | |
|       case KEY_KP_Multiply:
 | |
| 	xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
 | |
| 	break;
 | |
| 
 | |
|       /*
 | |
|        * Video mode switches
 | |
|        */
 | |
|       case KEY_KP_Minus:   /* Keypad - */
 | |
| 	if (down) xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
 | |
| 	if (!xf86Info.dontZoom) return;
 | |
| 	break;
 | |
| 	
 | |
|       case KEY_KP_Plus:   /* Keypad + */
 | |
| 	if (down) xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
 | |
| 	if (!xf86Info.dontZoom) return;
 | |
| 	break;
 | |
| 
 | |
| 	/* Under QNX4, we set the vtPending flag for VT switching and 
 | |
| 	 * let the VT switch function do the rest...
 | |
| 	 * This is a little different from the other OS'es.
 | |
| 	 */
 | |
| #if defined(QNX4)
 | |
|       case KEY_1:
 | |
|       case KEY_2:
 | |
|       case KEY_3:
 | |
|       case KEY_4:
 | |
|       case KEY_5:
 | |
|       case KEY_6:
 | |
|       case KEY_7:
 | |
|       case KEY_8:
 | |
|       case KEY_9:
 | |
| 	if (VTSwitchEnabled && !xf86Info.dontVTSwitch) {
 | |
| 	  if (down) {
 | |
| 	    int vtno = specialkey - KEY_1 + 1;
 | |
| 	    xf86ProcessActionEvent(ACTION_SWITCHSCREEN, (void *) &vtno);
 | |
| 	  }
 | |
| 	  return;
 | |
| 	}
 | |
| 	break;
 | |
| #endif
 | |
| 
 | |
| #if defined(linux) || (defined(CSRG_BASED) && (defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT))) || defined(__SCO__) || defined(__UNIXWARE__)
 | |
| 	/*
 | |
| 	 * Under Linux, the raw keycodes are consumed before the kernel
 | |
| 	 * does any processing on them, so we must emulate the vt switching
 | |
| 	 * we want ourselves.
 | |
| 	 */
 | |
|       case KEY_F1:
 | |
|       case KEY_F2:
 | |
|       case KEY_F3:
 | |
|       case KEY_F4:
 | |
|       case KEY_F5:
 | |
|       case KEY_F6:
 | |
|       case KEY_F7:
 | |
|       case KEY_F8:
 | |
|       case KEY_F9:
 | |
|       case KEY_F10:
 | |
|       case KEY_F11:
 | |
|       case KEY_F12:
 | |
| 	if ((VTSwitchEnabled && !xf86Info.vtSysreq && !xf86Info.dontVTSwitch)
 | |
| #if (defined(CSRG_BASED) && (defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)))
 | |
| 	    && (xf86Info.consType == SYSCONS || xf86Info.consType == PCVT)
 | |
| #endif
 | |
| 	   ) {
 | |
| 	    int vtno = specialkey - KEY_F1 + 1;
 | |
| 	    if (specialkey == KEY_F11 || specialkey == KEY_F12)
 | |
| 		vtno = specialkey - KEY_F11 + 11;
 | |
| 	    if (down)
 | |
| 		xf86ProcessActionEvent(ACTION_SWITCHSCREEN, (void *) &vtno);
 | |
| 	    return;
 | |
| 	}
 | |
| 	break;
 | |
| #endif /* linux || BSD with VTs */
 | |
| 
 | |
|       /* just worth mentioning here: any 386bsd keyboard driver
 | |
|        * (pccons.c or co_kbd.c) catches CTRL-ALT-DEL and CTRL-ALT-ESC
 | |
|        * before any application (e.g. XF86) will see it
 | |
|        * OBS: syscons does not, nor does pcvt !
 | |
|        */
 | |
|       } 
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Start of actual Solaris VT switching code.  
 | |
|      * This should pretty much emulate standard SVR4 switching keys.
 | |
|      * 
 | |
|      * DWH 12/2/93
 | |
|      */
 | |
| 
 | |
| #ifdef USE_VT_SYSREQ
 | |
|     if (VTSwitchEnabled && xf86Info.vtSysreq && !xf86Info.dontVTSwitch)
 | |
|     {
 | |
|       switch (specialkey)
 | |
|       {
 | |
|       /*
 | |
|        * syscons on *BSD doesn't have a VT #0  -- don't think Linux does
 | |
|        * either
 | |
|        */
 | |
| #if defined (sun) && defined (i386) && defined (SVR4)
 | |
|       case KEY_H: 
 | |
| 	if (VTSysreqToggle && down)
 | |
|         {
 | |
| 	  xf86ProcessActionEvent(ACTION_SWITCHSCREEN, NULL);
 | |
|           VTSysreqToggle = 0;
 | |
|           return; 
 | |
|         }
 | |
| 	break;
 | |
| 
 | |
|       /*
 | |
|        * Yah, I know the N, and P keys seem backwards, however that's
 | |
|        * how they work under Solaris
 | |
|        * XXXX N means go to next active VT not necessarily vtno+1 (or vtno-1)
 | |
|        */
 | |
| 
 | |
|       case KEY_N:
 | |
| 	if (VTSysreqToggle && down)
 | |
| 	{
 | |
| 	  xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT, NULL);
 | |
|           VTSysreqToggle = FALSE;
 | |
|           return;
 | |
|         }
 | |
| 	break;
 | |
| 
 | |
|       case KEY_P:
 | |
| 	if (VTSysreqToggle && down)
 | |
| 	{
 | |
| 	  xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT, NULL);
 | |
|           VTSysreqToggle = FALSE;
 | |
|           return;
 | |
|         }
 | |
| 	break;
 | |
| #endif
 | |
| 
 | |
|       case KEY_F1:
 | |
|       case KEY_F2:
 | |
|       case KEY_F3:
 | |
|       case KEY_F4:
 | |
|       case KEY_F5:
 | |
|       case KEY_F6:
 | |
|       case KEY_F7:
 | |
|       case KEY_F8:
 | |
|       case KEY_F9:
 | |
|       case KEY_F10:
 | |
|       case KEY_F11:
 | |
|       case KEY_F12:
 | |
| 	if (VTSysreqToggle && down)
 | |
| 	{ int vtno = specialkey - KEY_F1 + 1;
 | |
| 	  if (specialkey == KEY_F11 || specialkey == KEY_F12)
 | |
| 	    vtno = specialkey - KEY_F11 + 11;
 | |
| 	  xf86ProcessActionEvent(ACTION_SWITCHSCREEN, (void *) &vtno);
 | |
|           VTSysreqToggle = FALSE;
 | |
|           return;
 | |
|         }
 | |
| 	break;
 | |
| 
 | |
|       /* Ignore these keys -- ie don't let them cancel an alt-sysreq */
 | |
|       case KEY_Alt:
 | |
|       case KEY_AltLang:
 | |
| 	break;
 | |
| 
 | |
|       case KEY_SysReqest:
 | |
|         if (down && (ModifierDown(AltMask) || ModifierDown(AltLangMask)))
 | |
|           VTSysreqToggle = TRUE;
 | |
| 	break;
 | |
| 
 | |
|       default:
 | |
|         if (VTSysreqToggle)
 | |
| 	{
 | |
| 	  /*
 | |
| 	   * We only land here when Alt-SysReq is followed by a
 | |
| 	   * non-switching key.
 | |
| 	   */
 | |
|           VTSysreqToggle = FALSE;
 | |
| 
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
| #endif /* USE_VT_SYSREQ */
 | |
| 
 | |
| #ifdef __SCO__
 | |
|     /*
 | |
|      *	With the console in raw mode, SCO will not switch consoles,
 | |
|      *	you get around this by activating the next console along, if
 | |
|      *	this fails then go back to console 0, if there is only one
 | |
|      *	then it doesn't matter, switching to yourself is a nop as far
 | |
|      *	as the console driver is concerned.
 | |
|      *	We could do something similar to linux here but SCO ODT uses
 | |
|      *	Ctrl-PrintScrn, so why change?
 | |
|      */
 | |
|     if (specialkey == KEY_Print && ModifierDown(ControlMask)) {
 | |
|       if (down)
 | |
| 	xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT, NULL);
 | |
|       return;
 | |
|     }
 | |
| #endif /* __SCO__ */
 | |
| #ifdef XKB
 | |
|     }
 | |
| #endif
 | |
| 
 | |
|   /*
 | |
|    * Now map the scancodes to real X-keycodes ...
 | |
|    */
 | |
|   keycode = scanCode + MIN_KEYCODE;
 | |
|   keysym = (keyc->curKeySyms.map +
 | |
| 	    keyc->curKeySyms.mapWidth * 
 | |
| 	    (keycode - keyc->curKeySyms.minKeyCode));
 | |
| #ifdef XKB
 | |
|   if (noXkbExtension) {
 | |
| #endif
 | |
|   /*
 | |
|    * Filter autorepeated caps/num/scroll lock keycodes.
 | |
|    */
 | |
| #define CAPSFLAG 0x01
 | |
| #define NUMFLAG 0x02
 | |
| #define SCROLLFLAG 0x04
 | |
| #define MODEFLAG 0x08
 | |
|   if( down ) {
 | |
|     switch( keysym[0] ) {
 | |
|         case XK_Caps_Lock :
 | |
|           if (lockkeys & CAPSFLAG)
 | |
|               return;
 | |
| 	  else
 | |
| 	      lockkeys |= CAPSFLAG;
 | |
|           break;
 | |
| 
 | |
|         case XK_Num_Lock :
 | |
|           if (lockkeys & NUMFLAG)
 | |
|               return;
 | |
| 	  else
 | |
| 	      lockkeys |= NUMFLAG;
 | |
|           break;
 | |
| 
 | |
|         case XK_Scroll_Lock :
 | |
|           if (lockkeys & SCROLLFLAG)
 | |
|               return;
 | |
| 	  else
 | |
| 	      lockkeys |= SCROLLFLAG;
 | |
|           break;
 | |
|     }
 | |
|     if (keysym[1] == XF86XK_ModeLock)
 | |
|     {
 | |
|       if (lockkeys & MODEFLAG)
 | |
|           return;
 | |
|       else
 | |
|           lockkeys |= MODEFLAG;
 | |
|     }
 | |
|       
 | |
|   }
 | |
|   else {
 | |
|     switch( keysym[0] ) {
 | |
|         case XK_Caps_Lock :
 | |
|             lockkeys &= ~CAPSFLAG;
 | |
|             break;
 | |
| 
 | |
|         case XK_Num_Lock :
 | |
|             lockkeys &= ~NUMFLAG;
 | |
|             break;
 | |
| 
 | |
|         case XK_Scroll_Lock :
 | |
|             lockkeys &= ~SCROLLFLAG;
 | |
|             break;
 | |
|     }
 | |
|     if (keysym[1] == XF86XK_ModeLock)
 | |
|       lockkeys &= ~MODEFLAG;
 | |
|   }
 | |
| 
 | |
|   /*
 | |
|    * LockKey special handling:
 | |
|    * ignore releases, toggle on & off on presses.
 | |
|    * Don't deal with the Caps_Lock keysym directly, but check the lock modifier
 | |
|    */
 | |
|   if (keyc->modifierMap[keycode] & LockMask ||
 | |
|       keysym[0] == XK_Scroll_Lock ||
 | |
|       keysym[1] == XF86XK_ModeLock ||
 | |
|       keysym[0] == XK_Num_Lock)
 | |
|     {
 | |
|       Bool flag;
 | |
| 
 | |
|       if (!down) return;
 | |
|       if (KeyPressed(keycode)) {
 | |
| 	down = !down;
 | |
| 	flag = FALSE;
 | |
|       }
 | |
|       else
 | |
| 	flag = TRUE;
 | |
| 
 | |
|       if (keyc->modifierMap[keycode] & LockMask)   xf86Info.capsLock   = flag;
 | |
|       if (keysym[0] == XK_Num_Lock)    xf86Info.numLock    = flag;
 | |
|       if (keysym[0] == XK_Scroll_Lock) xf86Info.scrollLock = flag;
 | |
|       if (keysym[1] == XF86XK_ModeLock)   xf86Info.modeSwitchLock = flag;
 | |
|       updateLeds = TRUE;
 | |
|     }
 | |
| 
 | |
|   if (!xf86Info.kbdCustomKeycodes) {
 | |
|     /*
 | |
|      * normal, non-keypad keys
 | |
|      */
 | |
|     if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) {
 | |
| #if !defined(CSRG_BASED) && \
 | |
|     !defined(__GNU__) && \
 | |
|      defined(KB_84)
 | |
|       /*
 | |
|        * magic ALT_L key on AT84 keyboards for multilingual support
 | |
|        */
 | |
|       if (xf86Info.kbdType == KB_84 &&
 | |
| 	  ModifierDown(AltMask) &&
 | |
| 	  keysym[2] != NoSymbol)
 | |
| 	{
 | |
| 	  UsePrefix = TRUE;
 | |
| 	  Direction = TRUE;
 | |
| 	}
 | |
| #endif /* !CSRG_BASED && ... */
 | |
|     }
 | |
|   }
 | |
|   if (updateLeds) xf86UpdateKbdLeds();
 | |
| #ifdef XKB
 | |
|   }
 | |
| #endif
 | |
| 
 | |
|   /*
 | |
|    * check for an autorepeat-event
 | |
|    */
 | |
|   if (down && KeyPressed(keycode)) {
 | |
|       KbdFeedbackClassRec *kbdfeed = ((DeviceIntPtr)xf86Info.pKeyboard)->kbdfeed;
 | |
|       if ((xf86Info.autoRepeat != AutoRepeatModeOn) ||
 | |
|           keyc->modifierMap[keycode] ||
 | |
|           (kbdfeed && !(kbdfeed->ctrl.autoRepeats[keycode>>3] & ( 1<<(keycode&7) ))))
 | |
|           return;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   xf86Info.lastEventTime = kevent.u.keyButtonPointer.time = GetTimeInMillis();
 | |
|   /*
 | |
|    * And now send these prefixes ...
 | |
|    * NOTE: There cannot be multiple Mode_Switch keys !!!!
 | |
|    */
 | |
|   if (UsePrefix)
 | |
|     {
 | |
|       ENQUEUE(&kevent,
 | |
| 	      keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
 | |
| 	      (Direction ? KeyPress : KeyRelease),
 | |
| 	      XE_KEYBOARD);
 | |
|       ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
 | |
|       ENQUEUE(&kevent,
 | |
| 	      keyc->modifierKeyMap[keyc->maxKeysPerModifier*7],
 | |
| 	      (Direction ? KeyRelease : KeyPress),
 | |
| 	      XE_KEYBOARD);
 | |
|     }
 | |
|   else 
 | |
|     {
 | |
|       ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD);
 | |
|     }
 | |
| }
 | |
| #endif /* !__UNIXOS2__ */
 | |
| 
 | |
| #define ModifierIsSet(k) ((modifiers & (k)) == (k))
 | |
| 
 | |
| _X_EXPORT Bool
 | |
| xf86CommonSpecialKey(int key, Bool down, int modifiers)
 | |
| {
 | |
|   if ((!ModifierIsSet(ShiftMask)) &&
 | |
|       (((ModifierIsSet(ControlMask | AltMask)) ||
 | |
|         (ModifierIsSet(ControlMask | AltLangMask))))) {
 | |
|       switch (key) {
 | |
| 	
 | |
|       case KEY_BackSpace:
 | |
| 	xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
 | |
| 	break;
 | |
| 
 | |
|       /*
 | |
|        * Check grabs
 | |
|        */
 | |
|       case KEY_KP_Divide:
 | |
| 	xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
 | |
| 	break;
 | |
|       case KEY_KP_Multiply:
 | |
| 	xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
 | |
| 	break;
 | |
| 	
 | |
| 	/*
 | |
| 	 * The idea here is to pass the scancode down to a list of
 | |
| 	 * registered routines. There should be some standard conventions
 | |
| 	 * for processing certain keys.
 | |
| 	 */
 | |
|       case KEY_KP_Minus:   /* Keypad - */
 | |
| 	if (down) xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
 | |
| 	if (!xf86Info.dontZoom) return TRUE;
 | |
| 	break;
 | |
| 	
 | |
|       case KEY_KP_Plus:   /* Keypad + */
 | |
| 	if (down) xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
 | |
| 	if (!xf86Info.dontZoom) return TRUE;
 | |
| 	break;
 | |
|       }
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * xf86Wakeup --
 | |
|  *      Os wakeup handler.
 | |
|  */
 | |
| 
 | |
| /* ARGSUSED */
 | |
| void
 | |
| xf86Wakeup(pointer blockData, int err, pointer pReadmask)
 | |
| {
 | |
| #if !defined(__UNIXOS2__) && !defined(__QNX__)
 | |
|     fd_set* LastSelectMask = (fd_set*)pReadmask;
 | |
|     fd_set devicesWithInput;
 | |
|     InputInfoPtr pInfo;
 | |
| 
 | |
|     if (err >= 0) {
 | |
| 
 | |
| 	XFD_ANDSET(&devicesWithInput, LastSelectMask, &EnabledDevices);
 | |
| 	if (XFD_ANYSET(&devicesWithInput)) {
 | |
| 	    if (xf86Info.kbdEvents)
 | |
| 	    	(xf86Info.kbdEvents)();
 | |
| 	    pInfo = xf86InputDevs;
 | |
| 	    while (pInfo) {
 | |
| 		if (pInfo->read_input && pInfo->fd >= 0 &&
 | |
| 		    (FD_ISSET(pInfo->fd, &devicesWithInput) != 0)) {
 | |
| 		    int sigstate = xf86BlockSIGIO();
 | |
| 		    
 | |
| 		    pInfo->read_input(pInfo);
 | |
| 		    xf86UnblockSIGIO(sigstate);		    
 | |
| 		    /*
 | |
| 		     * Remove the descriptior from the set because more than one
 | |
| 		     * device may share the same file descriptor.
 | |
| 		     */
 | |
| 		    FD_CLR(pInfo->fd, &devicesWithInput);
 | |
| 		}
 | |
| 		pInfo = pInfo->next;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| #else   /* __UNIXOS2__ and __QNX__ */
 | |
| 
 | |
|     InputInfoPtr pInfo;
 | |
| 
 | |
|     (xf86Info.kbdEvents)();  /* Under OS/2 and QNX, always call */
 | |
| 
 | |
|     pInfo = xf86InputDevs;
 | |
|     while (pInfo) {
 | |
| 		if (pInfo->read_input && pInfo->fd >= 0) {
 | |
| 		    int sigstate = xf86BlockSIGIO();
 | |
| 		    
 | |
| 		    pInfo->read_input(pInfo);
 | |
| 		    xf86UnblockSIGIO(sigstate);		    
 | |
| 		    /*
 | |
| 		     * Must break here because more than one device may share
 | |
| 		     * the same file descriptor.
 | |
| 		     */
 | |
| 		    break;
 | |
| 		}
 | |
| 		pInfo = pInfo->next;
 | |
|     }
 | |
| 
 | |
| #endif  /* __UNIXOS2__ and __QNX__ */
 | |
| 
 | |
|     if (err >= 0) { /* we don't want the handlers called if select() */
 | |
| 	IHPtr ih;   /* returned with an error condition, do we?      */
 | |
| 	
 | |
| 	for (ih = InputHandlers; ih; ih = ih->next) {
 | |
| 	    if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
 | |
| 		(FD_ISSET(ih->fd, ((fd_set *)pReadmask)) != 0)) {
 | |
| 		ih->ihproc(ih->fd, ih->data);
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
|     
 | |
|     if (xf86VTSwitchPending()) xf86VTSwitch();
 | |
| 
 | |
|     if (xf86Info.inputPending) ProcessInputEvents();
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|  * xf86SigioReadInput --
 | |
|  *    signal handler for the SIGIO signal.
 | |
|  */
 | |
| static void
 | |
| xf86SigioReadInput(int fd,
 | |
| 		   void *closure)
 | |
| {
 | |
|     int sigstate = xf86BlockSIGIO();
 | |
|     InputInfoPtr pInfo = (InputInfoPtr) closure;
 | |
| 
 | |
|     pInfo->read_input(pInfo);
 | |
| 
 | |
|     xf86UnblockSIGIO(sigstate);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * xf86AddEnabledDevice --
 | |
|  *    
 | |
|  */
 | |
| _X_EXPORT void
 | |
| xf86AddEnabledDevice(InputInfoPtr pInfo)
 | |
| {
 | |
|     if (!xf86InstallSIGIOHandler (pInfo->fd, xf86SigioReadInput, pInfo)) {
 | |
| 	AddEnabledDevice(pInfo->fd);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * xf86RemoveEnabledDevice --
 | |
|  *    
 | |
|  */
 | |
| _X_EXPORT void
 | |
| xf86RemoveEnabledDevice(InputInfoPtr pInfo)
 | |
| {
 | |
|     if (!xf86RemoveSIGIOHandler (pInfo->fd)) {
 | |
| 	RemoveEnabledDevice(pInfo->fd);
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int *xf86SignalIntercept = NULL;
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86InterceptSignals(int *signo)
 | |
| {
 | |
|     if ((xf86SignalIntercept = signo))
 | |
| 	*signo = -1;
 | |
| }
 | |
| 
 | |
| static void (*xf86SigIllHandler)(void) = NULL;
 | |
| 
 | |
| _X_EXPORT void 
 | |
| xf86InterceptSigIll(void (*sigillhandler)(void))
 | |
| {
 | |
|     xf86SigIllHandler = sigillhandler;
 | |
| }
 | |
| 
 | |
| #ifdef HAVE_BACKTRACE
 | |
| #include <execinfo.h>
 | |
| 
 | |
| static __inline__ void xorg_backtrace(void)
 | |
| {
 | |
|     void *array[32]; /* deeper nesting than this means something's wrong */
 | |
|     size_t size, i;
 | |
|     char **strings;
 | |
|     ErrorF("\nBacktrace:\n");
 | |
|     size = backtrace(array, 32);
 | |
|     strings = backtrace_symbols(array, size);
 | |
|     for (i = 0; i < size; i++)
 | |
|         ErrorF("%d: %s\n", i, strings[i]);
 | |
|     free(strings);
 | |
| }
 | |
| 
 | |
| #else /* not glibc or glibc < 2.1 */
 | |
| 
 | |
| # if defined(sun) && defined(__SVR4)
 | |
| #  define HAVE_PSTACK
 | |
| # endif
 | |
| 
 | |
| # if defined(HAVE_WALKCONTEXT) /* Solaris 9 & later */
 | |
| 
 | |
| # include <ucontext.h>
 | |
| # include <signal.h>
 | |
| # include <dlfcn.h>
 | |
| # include <sys/elf.h>
 | |
| 
 | |
| #ifdef _LP64
 | |
| # define ElfSym Elf64_Sym
 | |
| #else
 | |
| # define ElfSym Elf32_Sym
 | |
| #endif
 | |
| 
 | |
| /* Called for each frame on the stack to print it's contents */
 | |
| static int xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
 | |
| {
 | |
|     Dl_info dlinfo;
 | |
|     ElfSym *dlsym;
 | |
|     char header[32];
 | |
|     int depth = *((int *) arg);
 | |
|     
 | |
|     if (signo) {
 | |
| 	char signame[SIG2STR_MAX];
 | |
| 
 | |
| 	if (sig2str(signo, signame) != 0) {
 | |
| 	    strcpy(signame, "unknown");
 | |
| 	}
 | |
| 
 | |
| 	ErrorF("** Signal %d (%s)\n", signo, signame);
 | |
|     }
 | |
| 
 | |
|     snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
 | |
|     *((int *) arg) = depth + 1;
 | |
|     
 | |
|     /* Ask system dynamic loader for info on the address */
 | |
|     if (dladdr1((void *) pc, &dlinfo, (void **) &dlsym, RTLD_DL_SYMENT)) {
 | |
| 	unsigned long offset = pc - (uintptr_t) dlinfo.dli_saddr;
 | |
| 	const char *symname;
 | |
| 	
 | |
| 	if (offset < dlsym->st_size) { /* inside a function */
 | |
| 	    symname = dlinfo.dli_sname;
 | |
| 	} else { /* found which file it was in, but not which function */
 | |
| 	    symname = "<section start>";
 | |
| 	    offset = pc - (uintptr_t)dlinfo.dli_fbase;
 | |
| 	}
 | |
| 	ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname,
 | |
| 	       symname, offset);
 | |
| 
 | |
|     } else {
 | |
| 	/* Couldn't find symbol info from system dynamic loader, should
 | |
| 	 * probably poke elfloader here, but haven't written that code yet,
 | |
| 	 * so we just print the pc.
 | |
| 	 */
 | |
| 	ErrorF("%s\n", header);
 | |
|     }
 | |
|     
 | |
|     return 0;
 | |
| }
 | |
| # endif /* HAVE_WALKCONTEXT */
 | |
| 
 | |
| # ifdef HAVE_PSTACK
 | |
| static int xorg_backtrace_pstack(void) {
 | |
|     pid_t kidpid;
 | |
|     int pipefd[2];
 | |
| 
 | |
|     if (pipe(pipefd) != 0) {
 | |
| 	return -1;
 | |
|     }
 | |
| 
 | |
|     kidpid = fork1();
 | |
| 
 | |
|     if (kidpid == -1) {
 | |
| 	/* ERROR */
 | |
| 	return -1;
 | |
|     } else if (kidpid == 0) {
 | |
| 	/* CHILD */
 | |
| 	char parent[16];
 | |
| 	
 | |
| 	seteuid(0);
 | |
| 	close(STDIN_FILENO);
 | |
| 	close(STDOUT_FILENO);
 | |
| 	dup2(pipefd[1],STDOUT_FILENO);
 | |
| 	closefrom(STDERR_FILENO);
 | |
| 
 | |
| 	snprintf(parent, sizeof(parent), "%d", getppid());
 | |
| 	execle("/usr/bin/pstack", "pstack", parent, NULL);
 | |
| 	exit(1);
 | |
|     } else {
 | |
| 	/* PARENT */
 | |
| 	char btline[256];
 | |
| 	int kidstat;
 | |
| 	int bytesread;
 | |
| 	int done = 0;
 | |
| 	
 | |
| 	close(pipefd[1]);
 | |
| 
 | |
| 	while (!done) {
 | |
| 	    bytesread = read(pipefd[0], btline, sizeof(btline) - 1);
 | |
| 	    
 | |
| 	    if (bytesread > 0) {
 | |
| 		btline[bytesread] = 0;
 | |
| 		ErrorF("%s", btline);
 | |
| 	    }
 | |
| 	    else if ((bytesread < 0) ||
 | |
| 		     ((errno != EINTR) && (errno != EAGAIN)))
 | |
| 		done = 1;
 | |
| 	}
 | |
| 	close(pipefd[0]);
 | |
| 	waitpid(kidpid, &kidstat, 0);
 | |
| 	if (kidstat != 0)
 | |
| 	    return -1;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| # endif /* HAVE_PSTACK */
 | |
| 
 | |
| 
 | |
| # if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
 | |
| 
 | |
| static __inline__ void xorg_backtrace(void) {
 | |
| 
 | |
|     ErrorF("\nBacktrace:\n");
 | |
|     
 | |
| #  ifdef HAVE_PSTACK    
 | |
| /* First try fork/exec of pstack - otherwise fall back to walkcontext
 | |
|    pstack is preferred since it can print names of non-exported functions */
 | |
|     
 | |
|     if (xorg_backtrace_pstack() < 0)
 | |
| #  endif	
 | |
|     {
 | |
| #  ifdef HAVE_WALKCONTEXT
 | |
| 	ucontext_t u;
 | |
| 	int depth = 1;
 | |
| 	
 | |
| 	if (getcontext(&u) == 0)
 | |
| 	    walkcontext(&u, xorg_backtrace_frame, &depth);
 | |
| 	else
 | |
| #  endif
 | |
| 	    Error("Failed to get backtrace info");
 | |
|     }
 | |
|     ErrorF("\n");	
 | |
| }
 | |
| 
 | |
| # else
 | |
| 
 | |
| /* Default fallback if we can't find any way to get a backtrace */
 | |
| static __inline__ void xorg_backtrace(void) { return; }
 | |
| 
 | |
| # endif
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * xf86SigHandler --
 | |
|  *    Catch unexpected signals and exit or continue cleanly.
 | |
|  */
 | |
| void
 | |
| xf86SigHandler(int signo)
 | |
| {
 | |
|   if ((signo == SIGILL) && xf86SigIllHandler) {
 | |
|     (*xf86SigIllHandler)();
 | |
|     /* Re-arm handler just in case we unexpectedly return here */
 | |
|     (void) signal(signo, xf86SigHandler);
 | |
|     return;
 | |
|   }
 | |
|   
 | |
|   if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
 | |
|     *xf86SignalIntercept = signo;
 | |
|     /* Re-arm handler just in case */
 | |
|     (void) signal(signo, xf86SigHandler);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   signal(signo,SIG_IGN);
 | |
|   xf86Info.caughtSignal = TRUE;
 | |
| #ifdef XF86BIGFONT
 | |
|   XF86BigfontCleanup();
 | |
| #endif
 | |
| 
 | |
|   xorg_backtrace();
 | |
|     
 | |
|   FatalError("Caught signal %d.  Server aborting\n", signo);
 | |
| }
 | |
| 
 | |
| #ifdef MEMDEBUG
 | |
| void
 | |
| xf86SigMemDebug(int signo)
 | |
| {
 | |
|     CheckMemory();
 | |
|     (void) signal(signo, xf86SigMemDebug);
 | |
|     return;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /*
 | |
|  * xf86VTSwitch --
 | |
|  *      Handle requests for switching the vt.
 | |
|  */
 | |
| static void
 | |
| xf86VTSwitch()
 | |
| {
 | |
|   int i, prevSIGIO;
 | |
|   InputInfoPtr pInfo;
 | |
|   IHPtr ih;
 | |
| 
 | |
| #ifdef DEBUG
 | |
|   ErrorF("xf86VTSwitch()\n");
 | |
| #endif
 | |
|   
 | |
| #ifdef XFreeXDGA
 | |
|   if(!DGAVTSwitch())
 | |
| 	return;
 | |
| #endif
 | |
| 
 | |
|   /*
 | |
|    * Since all screens are currently all in the same state it is sufficient
 | |
|    * check the first.  This might change in future.
 | |
|    */
 | |
|   if (xf86Screens[0]->vtSema) {
 | |
| 
 | |
| #ifdef DEBUG
 | |
|     ErrorF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
 | |
| 	   BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
 | |
| #endif
 | |
| #ifdef DPMSExtension
 | |
|     if (DPMSPowerLevel != DPMSModeOn)
 | |
| 	DPMSSet(DPMSModeOn);
 | |
| #endif
 | |
|     for (i = 0; i < xf86NumScreens; i++) {
 | |
|       if (!(dispatchException & DE_TERMINATE))
 | |
| 	if (xf86Screens[i]->EnableDisableFBAccess)
 | |
| 	  (*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
 | |
|     }
 | |
| #if !defined(__UNIXOS2__)
 | |
| 
 | |
|     /* 
 | |
|      * Keep the order: Disable Device > LeaveVT
 | |
|      *                        EnterVT > EnableDevice 
 | |
|      */
 | |
|     DisableDevice((DeviceIntPtr)xf86Info.pKeyboard);
 | |
|     pInfo = xf86InputDevs;
 | |
|     while (pInfo) {
 | |
|       DisableDevice(pInfo->dev);
 | |
|       pInfo = pInfo->next;
 | |
|     }
 | |
| #endif /* !__UNIXOS2__ */
 | |
|     xf86EnterServerState(SETUP);
 | |
|     for (i = 0; i < xf86NumScreens; i++)
 | |
| 	xf86Screens[i]->LeaveVT(i, 0);
 | |
| 
 | |
|     for (ih = InputHandlers; ih; ih = ih->next)
 | |
|       xf86DisableInputHandler(ih);
 | |
|     xf86AccessLeave();      /* We need this here, otherwise */
 | |
|     xf86AccessLeaveState(); /* console won't be restored    */
 | |
| 
 | |
|     if (!xf86VTSwitchAway()) {
 | |
|       /*
 | |
|        * switch failed 
 | |
|        */
 | |
| 
 | |
| #ifdef DEBUG
 | |
|       ErrorF("xf86VTSwitch: Leave failed\n");
 | |
| #endif
 | |
|       prevSIGIO = xf86BlockSIGIO();
 | |
|       xf86AccessEnter();
 | |
|       xf86EnterServerState(SETUP);
 | |
|       for (i = 0; i < xf86NumScreens; i++) {
 | |
| 	if (!xf86Screens[i]->EnterVT(i, 0))
 | |
| 	  FatalError("EnterVT failed for screen %d\n", i);
 | |
|       }
 | |
|       xf86EnterServerState(OPERATING);
 | |
|       if (!(dispatchException & DE_TERMINATE)) {
 | |
| 	for (i = 0; i < xf86NumScreens; i++) {
 | |
| 	  if (xf86Screens[i]->EnableDisableFBAccess)
 | |
| 	    (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
 | |
| 	}
 | |
|       }
 | |
|       SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
 | |
| 
 | |
| #if !defined(__UNIXOS2__)
 | |
|       EnableDevice((DeviceIntPtr)xf86Info.pKeyboard);
 | |
|       pInfo = xf86InputDevs;
 | |
|       while (pInfo) {
 | |
| 	EnableDevice(pInfo->dev);
 | |
| 	pInfo = pInfo->next;
 | |
|       }
 | |
| #endif /* !__UNIXOS2__ */
 | |
|       for (ih = InputHandlers; ih; ih = ih->next)
 | |
|         xf86EnableInputHandler(ih);
 | |
| 
 | |
|       xf86UnblockSIGIO(prevSIGIO);
 | |
| 
 | |
|     } else {
 | |
| #ifdef XF86PM
 | |
| 	  if (xf86OSPMClose)
 | |
| 	      xf86OSPMClose();
 | |
| 	  xf86OSPMClose = NULL;
 | |
| #endif
 | |
| 
 | |
| 	for (i = 0; i < xf86NumScreens; i++) {
 | |
|  	    /*
 | |
|  	     * zero all access functions to
 | |
|  	     * trap calls when switched away.
 | |
|  	     */
 | |
| 	    xf86Screens[i]->vtSema = FALSE;
 | |
| 	    xf86Screens[i]->access = NULL;
 | |
| 	    xf86Screens[i]->busAccess = NULL;
 | |
| 	}
 | |
| 	if (xorgHWAccess)
 | |
| 	    xf86DisableIO();
 | |
|     }
 | |
|   } else {
 | |
| 
 | |
| #ifdef DEBUG
 | |
|     ErrorF("xf86VTSwitch: Entering\n");
 | |
| #endif
 | |
|     if (!xf86VTSwitchTo()) return;
 | |
| 
 | |
|     prevSIGIO = xf86BlockSIGIO();
 | |
| #ifdef XF86PM
 | |
|     xf86OSPMClose = xf86OSPMOpen();
 | |
| #endif
 | |
| 
 | |
|     if (xorgHWAccess)
 | |
| 	xf86EnableIO();
 | |
|     xf86AccessEnter();
 | |
|     xf86EnterServerState(SETUP);
 | |
|     for (i = 0; i < xf86NumScreens; i++) {
 | |
|       xf86Screens[i]->vtSema = TRUE;
 | |
|       if (!xf86Screens[i]->EnterVT(i, 0))
 | |
| 	  FatalError("EnterVT failed for screen %d\n", i);
 | |
|     }
 | |
|     xf86EnterServerState(OPERATING);
 | |
|     for (i = 0; i < xf86NumScreens; i++) {
 | |
|       if (xf86Screens[i]->EnableDisableFBAccess)
 | |
| 	(*xf86Screens[i]->EnableDisableFBAccess)(i, TRUE);
 | |
|     }
 | |
| 
 | |
|     /* Turn screen saver off when switching back */
 | |
|     SaveScreens(SCREEN_SAVER_FORCER,ScreenSaverReset);
 | |
| 
 | |
| #if !defined(__UNIXOS2__)
 | |
|     EnableDevice((DeviceIntPtr)xf86Info.pKeyboard);
 | |
|     pInfo = xf86InputDevs;
 | |
|     while (pInfo) {
 | |
|       EnableDevice(pInfo->dev);
 | |
|       pInfo = pInfo->next;
 | |
|     }
 | |
| #endif /* !__UNIXOS2__ */
 | |
|     
 | |
|     for (ih = InputHandlers; ih; ih = ih->next)
 | |
|       xf86EnableInputHandler(ih);
 | |
| 
 | |
|     xf86UnblockSIGIO(prevSIGIO);
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /* Input handler registration */
 | |
| 
 | |
| _X_EXPORT pointer
 | |
| xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data)
 | |
| {
 | |
|     IHPtr ih;
 | |
| 
 | |
|     if (fd < 0 || !proc)
 | |
| 	return NULL;
 | |
| 
 | |
|     ih = xcalloc(sizeof(*ih), 1);
 | |
|     if (!ih)
 | |
| 	return NULL;
 | |
| 
 | |
|     ih->fd = fd;
 | |
|     ih->ihproc = proc;
 | |
|     ih->data = data;
 | |
|     ih->enabled = TRUE;
 | |
| 
 | |
|     ih->next = InputHandlers;
 | |
|     InputHandlers = ih;
 | |
| 
 | |
|     AddEnabledDevice(fd);
 | |
| 
 | |
|     return ih;
 | |
| }
 | |
| 
 | |
| _X_EXPORT int
 | |
| xf86RemoveInputHandler(pointer handler)
 | |
| {
 | |
|     IHPtr ih, p;
 | |
|     int fd;
 | |
|     
 | |
|     if (!handler)
 | |
| 	return -1;
 | |
| 
 | |
|     ih = handler;
 | |
|     fd = ih->fd;
 | |
|     
 | |
|     if (ih->fd >= 0)
 | |
| 	RemoveEnabledDevice(ih->fd);
 | |
| 
 | |
|     if (ih == InputHandlers)
 | |
| 	InputHandlers = ih->next;
 | |
|     else {
 | |
| 	p = InputHandlers;
 | |
| 	while (p && p->next != ih)
 | |
| 	    p = p->next;
 | |
| 	if (ih)
 | |
| 	    p->next = ih->next;
 | |
|     }
 | |
|     xfree(ih);
 | |
|     return fd;
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86DisableInputHandler(pointer handler)
 | |
| {
 | |
|     IHPtr ih;
 | |
| 
 | |
|     if (!handler)
 | |
| 	return;
 | |
| 
 | |
|     ih = handler;
 | |
|     ih->enabled = FALSE;
 | |
|     if (ih->fd >= 0)
 | |
| 	RemoveEnabledDevice(ih->fd);
 | |
| }
 | |
| 
 | |
| _X_EXPORT void
 | |
| xf86EnableInputHandler(pointer handler)
 | |
| {
 | |
|     IHPtr ih;
 | |
| 
 | |
|     if (!handler)
 | |
| 	return;
 | |
| 
 | |
|     ih = handler;
 | |
|     ih->enabled = TRUE;
 | |
|     if (ih->fd >= 0)
 | |
| 	AddEnabledDevice(ih->fd);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * As used currently by the DRI, the return value is ignored.
 | |
|  */
 | |
| _X_EXPORT Bool
 | |
| xf86EnableVTSwitch(Bool new)
 | |
| {
 | |
|     static Bool def = TRUE;
 | |
|     Bool old;
 | |
| 
 | |
|     old = VTSwitchEnabled;
 | |
|     if (!new) {
 | |
| 	/* Disable VT switching */
 | |
| 	def = VTSwitchEnabled;
 | |
| 	VTSwitchEnabled = FALSE;
 | |
|     } else {
 | |
| 	/* Restore VT switching to default */
 | |
| 	VTSwitchEnabled = def;
 | |
|     }
 | |
|     return old;
 | |
| }
 | |
| 
 | |
| void
 | |
| xf86ReloadInputDevs(int sig)
 | |
| {
 | |
|   InputInfoPtr pInfo;
 | |
|   
 | |
|   signal(sig, (void(*)(int))xf86ReloadInputDevs);
 | |
| 
 | |
|   DisableDevice((DeviceIntPtr)xf86Info.pKeyboard);
 | |
|   EnableDevice((DeviceIntPtr)xf86Info.pKeyboard);
 | |
| 
 | |
|   pInfo = xf86InputDevs;
 | |
|   while (pInfo) {
 | |
|     DisableDevice(pInfo->dev);
 | |
|     EnableDevice(pInfo->dev);
 | |
|     pInfo = pInfo->next;
 | |
|   }
 | |
|   
 | |
|   return;
 | |
| }
 | |
| 
 | |
| #ifdef WSCONS_SUPPORT
 | |
| 
 | |
| /* XXX Currently XKB is mandatory. */
 | |
| 
 | |
| extern int WSKbdToKeycode(int);
 | |
| 
 | |
| void
 | |
| xf86PostWSKbdEvent(struct wscons_event *event)
 | |
| {
 | |
|   int type = event->type;
 | |
|   int value = event->value;
 | |
|   unsigned int keycode;
 | |
|   int blocked;
 | |
|   
 | |
|   if (type == WSCONS_EVENT_KEY_UP || type == WSCONS_EVENT_KEY_DOWN) {
 | |
|     Bool down = (type == WSCONS_EVENT_KEY_DOWN ? TRUE : FALSE);
 | |
| 
 | |
|     /* map the scancodes to standard XFree86 scancode */  	
 | |
|     keycode = WSKbdToKeycode(value);
 | |
|     if (!down) keycode |= 0x80;
 | |
|     /* It seems better to block SIGIO there */
 | |
|     blocked = xf86BlockSIGIO();
 | |
|     xf86PostKbdEvent(keycode);
 | |
|     xf86UnblockSIGIO(blocked);
 | |
|   }
 | |
| }
 | |
| #endif /* WSCONS_SUPPORT */
 |