diff options
Diffstat (limited to 'nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c')
-rw-r--r-- | nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c new file mode 100644 index 000000000..861fbf089 --- /dev/null +++ b/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c @@ -0,0 +1,511 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c,v 3.16 2002/05/31 18:46:01 dawes Exp $ */ +/* + * (c) Copyright 1994,1996,1999 by Holger Veit + * <Holger.Veit@gmd.de> + * Modified 1996 Sebastien Marineau <marineau@genie.uottawa.ca> + * + * 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 + * HOLGER VEIT 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 Holger Veit shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Holger Veit. + * + */ +/* $XConsortium: os2_kbdEv.c /main/10 1996/10/27 11:48:48 kaleb $ */ + +#define I_NEED_OS2_H +#define NEED_EVENTS +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/X.h> +#include <X11/Xproto.h> +#include "misc.h" +#include "inputstr.h" +#include "scrnintstr.h" + +#define INCL_KBD +#define INCL_DOSMONITORS +#define INCL_WINSWITCHLIST +#define INCL_DOSQUEUES +#undef RT_FONT /* must discard this */ +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "atKeynames.h" + +/* Attention! these lines copied from ../../common/xf86Events.c */ +#define XE_POINTER 1 +#define XE_KEYBOARD 2 + +#ifdef XKB +extern Bool noXkbExtension; +#endif + +#ifdef XTESTEXT1 + +#define XTestSERVER_SIDE +#include <X11/extensions/xtestext1.h> +extern short xtest_mousex; +extern short xtest_mousey; +extern int on_steal_input; +extern Bool XTestStealKeyData(); +extern void XTestStealMotionData(); + +#ifdef XINPUT +#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)) \ + xf86eqEnqueue((ev)) +#else +#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)) \ + mieqEnqueue((ev)) +#endif + +#define MOVEPOINTER(dx, dy, time) \ + if (on_steal_input) \ + XTestStealMotionData(dx, dy, XE_POINTER, xtest_mousex, xtest_mousey); \ + miPointerDeltaCursor (dx, dy, time) + +#else /* ! XTESTEXT1 */ + +#ifdef XINPUT +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + xf86eqEnqueue((ev)) +#else +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + mieqEnqueue((ev)) +#endif +#define MOVEPOINTER(dx, dy, time) \ + miPointerDeltaCursor (dx, dy, time) + +#endif +/* end of include */ + +HQUEUE hKbdQueue; +HEV hKbdSem; +int last_status; +int lastStatus; +int lastShiftState; +extern BOOL SwitchedToWPS; + +void os2PostKbdEvent(); + +int os2KbdQueueQuery() +{ + ULONG numElements,postCount; + + (void)DosQueryQueue(hKbdQueue,&numElements); + if (numElements!=0) return 0; /* We have something in queue */ + + DosResetEventSem(hKbdSem,&postCount); + return 1; +} + + +void xf86KbdEvents() +{ + KBDKEYINFO keybuf; + ULONG numElements; + REQUESTDATA requestData; + ULONG dataLength, postCount; + PVOID dummy; + BYTE elemPriority; + int scan, down; + static int last; + USHORT ModState; + int i; + + while(DosReadQueue(hKbdQueue, + &requestData,&dataLength,&dummy, + 0L,1L,&elemPriority,hKbdSem) == 0) { + + /* xf86Msg(X_INFO, + "Got queue element. data=%d, scancode =%d,up=%d, ddflag %d\n", + requestData.ulData, + (requestData.ulData&0x7F00)>>8, + requestData.ulData&0x8000, + requestData.ulData>>16);*/ + + scan=(requestData.ulData&0x7F00)>>8; + + /* the separate cursor keys return 0xe0/scan */ + if ((requestData.ulData & 0x3F0000)==0x20000) scan=0; + if (requestData.ulData & 0x800000) { + switch (scan) { + +/* BUG ALERT: IBM has in its keyboard driver a 122 key keyboard, which + * uses the "server generated scancodes" from atKeynames.h as real scan codes. + * We wait until some poor guy with such a keyboard will break the whole + * card house though... + */ + case KEY_KP_7: scan = KEY_Home; break; + case KEY_KP_8: scan = KEY_Up; break; + case KEY_KP_9: scan = KEY_PgUp; break; + case KEY_KP_4: scan = KEY_Left; break; + case KEY_KP_5: scan = KEY_Begin; break; + case KEY_KP_6: scan = KEY_Right; break; + case KEY_KP_1: scan = KEY_End; break; + case KEY_KP_2: scan = KEY_Down; break; + case KEY_KP_3: scan = KEY_PgDown; break; + case KEY_KP_0: scan = KEY_Insert; break; + case KEY_KP_Decimal: scan = KEY_Delete; break; + case KEY_Enter: scan = KEY_KP_Enter; break; + case KEY_LCtrl: scan = KEY_RCtrl; break; + case KEY_KP_Multiply: scan = KEY_Print; break; + case KEY_Slash: scan = KEY_KP_Divide; break; + case KEY_Alt: scan = KEY_AltLang; break; + case KEY_ScrollLock: scan = KEY_Break; break; + case 0x5b: scan = KEY_LMeta; break; + case 0x5c: scan = KEY_RMeta; break; + case 0x5d: scan = KEY_Menu; break; + default: + /* virtual shifts: ignore */ + scan = 0; break; + } + } + + down = (requestData.ulData&0x8000) ? FALSE : TRUE; + if (scan!=0) os2PostKbdEvent(scan, down); + } + (void)DosResetEventSem(hKbdSem,&postCount); +} + +/* + * 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 from common/xf86Events.c + * as some things differ, and I didn't want to scatter this routine with + * ifdefs further (hv). + */ + +void os2PostKbdEvent(unsigned scanCode, Bool down) +{ + 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; + + /* + * and now get some special keysequences + */ + if ((ModifierDown(ControlMask | AltMask)) || + (ModifierDown(ControlMask | AltLangMask))) { + switch (scanCode) { + case KEY_BackSpace: + if (!xf86Info.dontZap) GiveUp(0); + return; + case KEY_KP_Minus: /* Keypad - */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, -1); + return; + } + break; + case KEY_KP_Plus: /* Keypad + */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, 1); + return; + } + break; + } + } + + /* CTRL-ESC is std OS/2 hotkey for going back to PM and popping up + * window list... handled by keyboard driverand PM if you tell it. This is + * what we have done, and thus should never detect this key combo */ + if (ModifierDown(ControlMask) && scanCode==KEY_Escape) { + /* eat it */ + return; + } else if (ModifierDown(AltLangMask|AltMask) && scanCode==KEY_Escape) { + /* same here */ + return; + } + + /* + * 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 + */ +#ifndef PC98 + if (keyc->modifierMap[keycode] & LockMask || + keysym[0] == XK_Scroll_Lock || + keysym[1] == XF86XK_ModeLock || + keysym[0] == XK_Num_Lock) { + Bool flag; + + if (!down) return; + flag = !KeyPressed(keycode); + if (!flag) down = !down; + + 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; + } +#endif /* not PC98 */ + + /* normal, non-keypad keys */ + if (scanCode < KEY_KP_7 || scanCode > KEY_KP_Decimal) { + /* magic ALT_L key on AT84 keyboards for multilingual support */ + if (xf86Info.kbdType == KB_84 && + ModifierDown(AltMask) && + keysym[2] != NoSymbol) { + UsePrefix = TRUE; + Direction = TRUE; + } + } + +#ifdef XKB /* Warning: got position wrong first time */ + } +#endif + + /* check for an autorepeat-event */ + if ((down && KeyPressed(keycode)) && + (xf86Info.autoRepeat != AutoRepeatModeOn || keyc->modifierMap[keycode])) + 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 { +#ifdef XFreeDGA + if (((ScrnInfoPtr)(xf86Info.currentScreen->devPrivates[xf86ScreenIndex].ptr))->directMode&XF86DGADirectKeyb) { + XF86DirectVideoKeyEvent(&kevent, + keycode, + down ? KeyPress : KeyRelease); + } else +#endif + { + ENQUEUE(&kevent, + keycode, + down ? KeyPress : KeyRelease, + XE_KEYBOARD); + } + } + + if (updateLeds) xf86KbdLeds(); +} + +#pragma pack(1) +struct KeyPacket { + unsigned short mnflags; + KBDKEYINFO cp; + unsigned short ddflags; +}; +#pragma pack() + +/* The next function runs as a thread. It registers a monitor on the kbd + * driver, and uses that to get keystrokes. This is because the standard + * OS/2 keyboard driver does not send keyboard release events. A queue + * is used to communicate with the main thread to send keystrokes */ + +void os2KbdMonitorThread(void* arg) +{ + struct KeyPacket packet; + APIRET rc; + USHORT length,print_flag; + ULONG queueParam; + HMONITOR hKbdMonitor; + MONIN monInbuf; + MONOUT monOutbuf; + char queueName[128]; + +#if 0 + monInbuf=(MONIN *)_tmalloc(2*sizeof(MONIN)); + if (monInbuf==NULL) { + xf86Msg(X_ERROR, + "Could not allocate memory in kbd monitor thread!\n"); + exit(1); + } + monOutbuf=(MONOUT *) &monInbuf[1]; +#endif + + monInbuf.cb=sizeof(MONIN); + monOutbuf.cb=sizeof(MONOUT); + + rc = DosMonOpen("KBD$",&hKbdMonitor); + xf86Msg(X_INFO,"Opened kbd monitor, rc=%d\n",rc); + rc = DosMonReg(hKbdMonitor, + (PBYTE)&monInbuf,(PBYTE)&monOutbuf,(USHORT)2,(USHORT)-1); + xf86Msg(X_INFO,"Kbd monitor registered, rc=%d\n",rc); + if (rc) { + DosMonClose(hKbdMonitor); + exit(1); + } + + /* create a queue */ + sprintf(queueName,"\\QUEUES\\XF86KBD\\%d",getpid()); + rc = DosCreateQueue(&hKbdQueue,0L,queueName); + xf86Msg(X_INFO,"Kbd Queue created, rc=%d\n",rc); + (void)DosPurgeQueue(hKbdQueue); + + while (1) { + length = sizeof(packet); + rc = DosMonRead((PBYTE)&monInbuf,0,(PBYTE)&packet,&length); + if (rc) { + xf86Msg(X_ERROR, + "DosMonRead returned bad RC! rc=%d\n",rc); + DosMonClose(hKbdMonitor); + exit(1); + } + queueParam = packet.mnflags+(packet.ddflags<<16); + if (packet.mnflags&0x7F00) + DosWriteQueue(hKbdQueue,queueParam,0L,NULL,0L); + /*xf86Msg(X_INFO,"Wrote a char to queue, rc=%d\n",rc); */ + print_flag = packet.ddflags & 0x1F; + + /*xf86Msg(X_INFO,"Kbd Monitor: Key press %d, scan code %d, ddflags %d\n", + packet.mnflags&0x8000,(packet.mnflags&0x7F00)>>8,packet.ddflags); + */ + + /* This line will swallow print-screen keypresses */ + if (print_flag == 0x13 || print_flag == 0x14 || + print_flag == 0x15 || print_flag == 0x16) + rc = 0; + else + rc = DosMonWrite((PBYTE)&monOutbuf,(PBYTE)&packet,length); + if (rc) { + xf86Msg(X_ERROR, + "DosMonWrite returned bad RC! rc=%d\n",rc); + DosMonClose(hKbdMonitor); + exit(1); + } + } + + DosCloseQueue(hKbdQueue); + DosMonClose(hKbdMonitor); +} + +void os2KbdBitBucketThread(void* arg) +{ + KBDKEYINFO key; + while (1) { + if (xf86Info.consoleFd != -1) { + KbdCharIn(&key,1,xf86Info.consoleFd); + usleep(100000); + } else + usleep(500000); + } +} |