#ifdef __UNIXOS2__
#define I_NEED_OS2_H
#endif
#include "X.h"
#include "Xpoll.h"
#include "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 "XI.h"
#include "XIproto.h"
#else
#include "inputstr.h"
#endif
#include "xf86Xinput.h"
#include "mi.h"
#include "mipointer.h"
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
#include "xf86bigfont.h"
#endif
#ifdef XKB
extern Bool noXkbExtension;
#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); \
}
#ifdef XTESTEXT1
#define XTestSERVER_SIDE
#include "xtestext1.h"
extern short xtest_mousex;
extern short xtest_mousey;
extern int on_steal_input;
extern Bool XTestStealKeyData();
extern void XTestStealMotionData();
#define ENQUEUE(ev, code, direction, dev_type) \
(ev)->u.u.detail = (code); \
(ev)->u.u.type = (direction); \
if (!on_steal_input || \
XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \
xtest_mousex, xtest_mousey)) \
EqEnqueue((ev))
#else
#define ENQUEUE(ev, code, direction, dev_type) \
(ev)->u.u.detail = (code); \
(ev)->u.u.type = (direction); \
EqEnqueue((ev))
#endif
#ifdef USE_VT_SYSREQ
Bool VTSysreqToggle = FALSE;
#endif
Bool VTSwitchEnabled = TRUE;
extern fd_set EnabledDevices;
#if defined(XQUEUE)
extern void xf86XqueRequest(void);
#endif
extern void (*xf86OSPMClose)(void);
static void xf86VTSwitch(void);
typedef struct x_IHRec {
int fd;
InputHandlerProc ihproc;
pointer data;
Bool enabled;
struct x_IHRec * next;
} IHRec, *IHPtr;
static IHPtr InputHandlers = NULL;
int
TimeSinceLastInputEvent()
{
if (xf86Info.lastEventTime == 0) {
xf86Info.lastEventTime = GetTimeInMillis();
}
return GetTimeInMillis() - xf86Info.lastEventTime;
}
void
SetTimeSinceLastInputEvent()
{
xf86Info.lastEventTime = GetTimeInMillis();
}
void
ProcessInputEvents ()
{
int x, y;
#ifdef INHERIT_LOCK_STATE
static int generation = 0;
#endif
#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;
}
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);
#ifdef SCO
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) {
#if defined(SCO)
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))
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
if (*pScr->HandleMessage) {
(void) (*pScr->HandleMessage)(pScr->scrnIndex,
"KeyEventMessage", message, &retstr);
}
}
break;
default:
break;
}
}
#ifdef __linux__
extern u_char SpecialServerMap[];
#endif
#if !defined(__UNIXOS2__) && \
!defined(__SOL8__) && \
(!defined(sun) || defined(i386))
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
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
#ifdef __linux__
if (xf86Info.kbdCustomKeycodes) {
specialkey = SpecialServerMap[scanCode];
goto customkeycodes;
}
#endif
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;
return;
#if defined(PCCONS_SUPPORT) || defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
}
break;
#endif
}
#if defined (i386) && defined (SVR4)
if(xf86Info.panix106 == TRUE){
switch (scanCode) {
case 0x56: scanCode = KEY_BSlash2; break;
case 0x5A: scanCode = KEY_NFER; break;
case 0x5B: scanCode = KEY_XFER; break;
case 0x5C: scanCode = KEY_Yen; break;
case 0x6B: scanCode = KEY_Left; break;
case 0x6F: scanCode = KEY_PgUp; break;
case 0x72: scanCode = KEY_AltLang; break;
case 0x73: scanCode = KEY_RCtrl; break;
}
} else
#endif
{
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;
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;
case KEY_KP_8: scanCode = KEY_Up; break;
case KEY_KP_9: scanCode = KEY_PgUp; break;
case KEY_KP_4: scanCode = KEY_Left; break;
case KEY_KP_5: scanCode = KEY_Begin; break;
case KEY_KP_6: scanCode = KEY_Right; break;
case KEY_KP_1: scanCode = KEY_End; break;
case KEY_KP_2: scanCode = KEY_Down; break;
case KEY_KP_3: scanCode = KEY_PgDown; break;
case KEY_KP_0: scanCode = KEY_Insert; break;
case KEY_KP_Decimal: scanCode = KEY_Delete; break;
case KEY_Enter: scanCode = KEY_KP_Enter; break;
case KEY_LCtrl: scanCode = KEY_RCtrl; break;
case KEY_KP_Multiply: scanCode = KEY_Print; break;
case KEY_Slash: scanCode = KEY_KP_Divide; break;
case KEY_Alt: scanCode = KEY_AltLang; break;
case KEY_ScrollLock: scanCode = KEY_Break; 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;
case 0x2A:
case 0x36:
return;
default:
xf86MsgVerb(X_INFO, 4, "Unreported Prefix0 scancode: 0x%02x\n",
scanCode);
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;
}
#ifndef __sparc64__
if (scanCode == KEY_SysReqest)
scanCode = KEY_Print;
else if (scanCode == KEY_Break)
scanCode = KEY_Pause;
#endif
specialkey = scanCode;
#ifdef __linux__
customkeycodes:
#endif
#if defined(i386) || defined(__i386__)
if (xf86IsPc98()) {
switch (scanCode) {
case 0x0e: specialkey = 0x0e; break;
case 0x40: specialkey = 0x4a; break;
case 0x49: specialkey = 0x4e; break;
case 0x62: specialkey = 0x3b; break;
case 0x63: specialkey = 0x3c; break;
case 0x64: specialkey = 0x3d; break;
case 0x65: specialkey = 0x3e; break;
case 0x66: specialkey = 0x3f; break;
case 0x67: specialkey = 0x40; break;
case 0x68: specialkey = 0x41; break;
case 0x69: specialkey = 0x42; break;
case 0x6a: specialkey = 0x43; break;
case 0x6b: specialkey = 0x44; break;
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;
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;
}
scanCode--;
}
#endif
#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;
case KEY_KP_Divide:
xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
break;
case KEY_KP_Multiply:
xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
break;
case KEY_KP_Minus:
if (down) xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
if (!xf86Info.dontZoom) return;
break;
case KEY_KP_Plus:
if (down) xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
if (!xf86Info.dontZoom) return;
break;
#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)
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
}
}
#ifdef USE_VT_SYSREQ
if (VTSwitchEnabled && xf86Info.vtSysreq && !xf86Info.dontVTSwitch)
{
switch (specialkey)
{
#if defined (sun) && defined (i386) && defined (SVR4)
case KEY_H:
if (VTSysreqToggle && down)
{
xf86ProcessActionEvent(ACTION_SWITCHSCREEN, NULL);
VTSysreqToggle = 0;
return;
}
break;
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;
case KEY_Alt:
case KEY_AltLang:
break;
case KEY_SysReqest:
if (down && (ModifierDown(AltMask) || ModifierDown(AltLangMask)))
VTSysreqToggle = TRUE;
break;
default:
if (VTSysreqToggle)
{
VTSysreqToggle = FALSE;
}
}
}
#endif
#ifdef SCO
if (specialkey == KEY_Print && ModifierDown(ControlMask)) {
if (down)
xf86ProcessActionEvent(ACTION_SWITCHSCREEN_NEXT, NULL);
return;
}
#endif
#ifdef XKB
}
#endif
keycode = scanCode + MIN_KEYCODE;
keysym = (keyc->curKeySyms.map +
keyc->curKeySyms.mapWidth *
(keycode - keyc->curKeySyms.minKeyCode));
#ifdef XKB
if (noXkbExtension) {
#endif
#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;
}
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) {
if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) {
#if !defined(CSRG_BASED) && \
!defined(__GNU__) && \
defined(KB_84)
if (xf86Info.kbdType == KB_84 &&
ModifierDown(AltMask) &&
keysym[2] != NoSymbol)
{
UsePrefix = TRUE;
Direction = TRUE;
}
#endif
}
}
if (updateLeds) xf86UpdateKbdLeds();
#ifdef XKB
}
#endif
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();
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
#define ModifierIsSet(k) ((modifiers & (k)) == (k))
Bool
xf86CommonSpecialKey(int key, Bool down, int modifiers)
{
if ((ModifierIsSet(ControlMask | AltMask)) ||
(ModifierIsSet(ControlMask | AltLangMask))) {
switch (key) {
case KEY_BackSpace:
xf86ProcessActionEvent(ACTION_TERMINATE, NULL);
break;
case KEY_KP_Divide:
xf86ProcessActionEvent(ACTION_DISABLEGRAB, NULL);
break;
case KEY_KP_Multiply:
xf86ProcessActionEvent(ACTION_CLOSECLIENT, NULL);
break;
case KEY_KP_Minus:
if (down) xf86ProcessActionEvent(ACTION_PREV_MODE, NULL);
if (!xf86Info.dontZoom) return TRUE;
break;
case KEY_KP_Plus:
if (down) xf86ProcessActionEvent(ACTION_NEXT_MODE, NULL);
if (!xf86Info.dontZoom) return TRUE;
break;
}
}
return FALSE;
}
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);
FD_CLR(pInfo->fd, &devicesWithInput);
}
pInfo = pInfo->next;
}
}
}
#else
InputInfoPtr pInfo;
(xf86Info.kbdEvents)();
pInfo = xf86InputDevs;
while (pInfo) {
if (pInfo->read_input && pInfo->fd >= 0) {
int sigstate = xf86BlockSIGIO();
pInfo->read_input(pInfo);
xf86UnblockSIGIO(sigstate);
break;
}
pInfo = pInfo->next;
}
#endif
if (err >= 0) {
IHPtr ih;
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();
}
static void
xf86SigioReadInput(int fd,
void *closure)
{
int sigstate = xf86BlockSIGIO();
InputInfoPtr pInfo = (InputInfoPtr) closure;
pInfo->read_input(pInfo);
xf86UnblockSIGIO(sigstate);
}
void
xf86AddEnabledDevice(InputInfoPtr pInfo)
{
if (!xf86InstallSIGIOHandler (pInfo->fd, xf86SigioReadInput, pInfo)) {
AddEnabledDevice(pInfo->fd);
}
}
void
xf86RemoveEnabledDevice(InputInfoPtr pInfo)
{
if (!xf86RemoveSIGIOHandler (pInfo->fd)) {
RemoveEnabledDevice(pInfo->fd);
}
}
static int *xf86SignalIntercept = NULL;
void
xf86InterceptSignals(int *signo)
{
if ((xf86SignalIntercept = signo))
*signo = -1;
}
void
xf86SigHandler(int signo)
{
if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
(void) signal(signo, xf86SigHandler);
*xf86SignalIntercept = signo;
return;
}
signal(signo,SIG_IGN);
xf86Info.caughtSignal = TRUE;
#ifdef XF86BIGFONT
XF86BigfontCleanup();
#endif
#if defined(XFree86LOADER)
if (xf86Initialising)
LoaderCheckUnresolved(LD_RESOLV_IFDONE);
ErrorF("\n"
" *** If unresolved symbols were reported above, they might not\n"
" *** be the reason for the server aborting.\n");
#endif
FatalError("Caught signal %d. Server aborting\n", signo);
}
#ifdef MEMDEBUG
void
xf86SigMemDebug(int signo)
{
CheckMemory();
(void) signal(signo, xf86SigMemDebug);
return;
}
#endif
static void
xf86VTSwitch()
{
int i, prevSIGIO;
InputInfoPtr pInfo;
IHPtr ih;
#ifdef DEBUG
ErrorF("xf86VTSwitch()\n");
#endif
#ifdef XFreeXDGA
if(!DGAVTSwitch())
return;
#endif
if (xf86Screens[0]->vtSema) {
#ifdef DEBUG
ErrorF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
#endif
for (i = 0; i < xf86NumScreens; i++) {
if (!(dispatchException & DE_TERMINATE))
if (xf86Screens[i]->EnableDisableFBAccess)
(*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
}
#if !defined(__UNIXOS2__)
DisableDevice((DeviceIntPtr)xf86Info.pKeyboard);
pInfo = xf86InputDevs;
while (pInfo) {
DisableDevice(pInfo->dev);
pInfo = pInfo->next;
}
#endif
xf86EnterServerState(SETUP);
for (i = 0; i < xf86NumScreens; i++) {
xf86Screens[i]->LeaveVT(i, 0);
}
for (ih = InputHandlers; ih; ih = ih->next)
xf86DisableInputHandler(ih);
xf86AccessLeave();
xf86AccessLeaveState();
if (!xf86VTSwitchAway()) {
#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
for (ih = InputHandlers; ih; ih = ih->next)
xf86EnableInputHandler(ih);
xf86UnblockSIGIO(prevSIGIO);
} else {
if (xf86OSPMClose)
xf86OSPMClose();
xf86OSPMClose = NULL;
for (i = 0; i < xf86NumScreens; i++) {
xf86Screens[i]->vtSema = FALSE;
xf86Screens[i]->access = NULL;
xf86Screens[i]->busAccess = NULL;
}
xf86DisableIO();
}
} else {
#ifdef DEBUG
ErrorF("xf86VTSwitch: Entering\n");
#endif
if (!xf86VTSwitchTo()) return;
prevSIGIO = xf86BlockSIGIO();
xf86OSPMClose = xf86OSPMOpen();
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);
}
SaveScreens(SCREEN_SAVER_FORCER,ScreenSaverReset);
#if !defined(__UNIXOS2__)
EnableDevice((DeviceIntPtr)xf86Info.pKeyboard);
pInfo = xf86InputDevs;
while (pInfo) {
EnableDevice(pInfo->dev);
pInfo = pInfo->next;
}
#endif
for (ih = InputHandlers; ih; ih = ih->next)
xf86EnableInputHandler(ih);
xf86UnblockSIGIO(prevSIGIO);
}
}
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;
}
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;
}
void
xf86DisableInputHandler(pointer handler)
{
IHPtr ih;
if (!handler)
return;
ih = handler;
ih->enabled = FALSE;
if (ih->fd >= 0)
RemoveEnabledDevice(ih->fd);
}
void
xf86EnableInputHandler(pointer handler)
{
IHPtr ih;
if (!handler)
return;
ih = handler;
ih->enabled = TRUE;
if (ih->fd >= 0)
AddEnabledDevice(ih->fd);
}
Bool
xf86EnableVTSwitch(Bool new)
{
static Bool def = TRUE;
Bool old;
old = VTSwitchEnabled;
if (!new) {
def = VTSwitchEnabled;
VTSwitchEnabled = FALSE;
} else {
VTSwitchEnabled = def;
}
return old;
}
#ifdef XTESTEXT1
void
XTestGetPointerPos(short *fmousex, short *fmousey)
{
int x,y;
miPointerPosition(&x, &y);
*fmousex = x;
*fmousey = y;
}
void
XTestJumpPointer(int jx, int jy, int dev_type)
{
miPointerAbsoluteCursor(jx, jy, GetTimeInMillis() );
}
void
XTestGenerateEvent(int dev_type, int keycode, int keystate, int mousex,
int mousey)
{
xEvent tevent;
tevent.u.u.type = (dev_type == XE_POINTER) ?
(keystate == XTestKEY_UP) ? ButtonRelease : ButtonPress :
(keystate == XTestKEY_UP) ? KeyRelease : KeyPress;
tevent.u.u.detail = keycode;
tevent.u.keyButtonPointer.rootX = mousex;
tevent.u.keyButtonPointer.rootY = mousey;
tevent.u.keyButtonPointer.time = xf86Info.lastEventTime = GetTimeInMillis();
#ifdef XINPUT
xf86eqEnqueue(&tevent);
#else
mieqEnqueue(&tevent);
#endif
xf86Info.inputPending = TRUE;
}
#endif
#ifdef WSCONS_SUPPORT
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);
keycode = WSKbdToKeycode(value);
if (!down) keycode |= 0x80;
blocked = xf86BlockSIGIO();
xf86PostKbdEvent(keycode);
xf86UnblockSIGIO(blocked);
}
}
#endif