aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/Xserver/hw/xfree86/os-support/os2/os2_kbdEv.c
diff options
context:
space:
mode:
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.c511
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);
+ }
+}