+++ /dev/null
-/*
- * kbdptr.c - deal with keyboard and pointer device over TCP & UDP.
- *
- *
- */
-
-/*
- * Copyright (C) 2002-2003 RealVNC Ltd.
- * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this software; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
- */
-
-#include <stdio.h>
-
-#include "X11/X.h"
-#define NEED_EVENTS
-#include "X11/Xproto.h"
-#include "inputstr.h"
-#define XK_CYRILLIC
-#include <X11/keysym.h>
-#include <mi.h>
-#include <mipointer.h>
-#include <property.h>
-#include <Xatom.h>
-#include "rfb.h"
-
-extern WindowPtr *WindowTable; /* Why isn't this in a header file? */
-
-#define KEY_IS_PRESSED(keycode) \
- (kbdDevice->key->down[(keycode) >> 3] & (1 << ((keycode) & 7)))
-
-
-static void XConvertCase(KeySym sym, KeySym *lower, KeySym *upper);
-
-static DeviceIntPtr kbdDevice;
-
-#define MIN_KEY_CODE 8
-#define MAX_KEY_CODE 255
-#define NO_OF_KEYS (MAX_KEY_CODE - MIN_KEY_CODE + 1)
-#define GLYPHS_PER_KEY 2
-
-static KeySym kbdMap[] = {
-
- /* Modifiers */
-
- XK_Control_L, NoSymbol,
-#define CONTROL_L_KEY_CODE MIN_KEY_CODE
-
- XK_Control_R, NoSymbol,
-#define CONTROL_R_KEY_CODE (MIN_KEY_CODE + 1)
-
- XK_Shift_L, NoSymbol,
-#define SHIFT_L_KEY_CODE (MIN_KEY_CODE + 2)
-
- XK_Shift_R, NoSymbol,
-#define SHIFT_R_KEY_CODE (MIN_KEY_CODE + 3)
-
- XK_Meta_L, NoSymbol,
-#define META_L_KEY_CODE (MIN_KEY_CODE + 4)
-
- XK_Meta_R, NoSymbol,
-#define META_R_KEY_CODE (MIN_KEY_CODE + 5)
-
- XK_Alt_L, NoSymbol,
-#define ALT_L_KEY_CODE (MIN_KEY_CODE + 6)
-
- XK_Alt_R, NoSymbol,
-#define ALT_R_KEY_CODE (MIN_KEY_CODE + 7)
-
- /* Standard US keyboard */
-
- XK_space, NoSymbol,
- XK_0, XK_parenright,
- XK_1, XK_exclam,
- XK_2, XK_at,
- XK_3, XK_numbersign,
- XK_4, XK_dollar,
- XK_5, XK_percent,
- XK_6, XK_asciicircum,
- XK_7, XK_ampersand,
- XK_8, XK_asterisk,
- XK_9, XK_parenleft,
-
- XK_minus, XK_underscore,
- XK_equal, XK_plus,
- XK_bracketleft, XK_braceleft,
- XK_bracketright, XK_braceright,
- XK_semicolon, XK_colon,
- XK_apostrophe, XK_quotedbl,
- XK_grave, XK_asciitilde,
- XK_comma, XK_less,
- XK_period, XK_greater,
- XK_slash, XK_question,
- XK_backslash, XK_bar,
-
- XK_a, XK_A,
- XK_b, XK_B,
- XK_c, XK_C,
- XK_d, XK_D,
- XK_e, XK_E,
- XK_f, XK_F,
- XK_g, XK_G,
- XK_h, XK_H,
- XK_i, XK_I,
- XK_j, XK_J,
- XK_k, XK_K,
- XK_l, XK_L,
- XK_m, XK_M,
- XK_n, XK_N,
- XK_o, XK_O,
- XK_p, XK_P,
- XK_q, XK_Q,
- XK_r, XK_R,
- XK_s, XK_S,
- XK_t, XK_T,
- XK_u, XK_U,
- XK_v, XK_V,
- XK_w, XK_W,
- XK_x, XK_X,
- XK_y, XK_Y,
- XK_z, XK_Z,
-
- /* Other useful keys */
-
- XK_BackSpace, NoSymbol,
- XK_Return, NoSymbol,
- XK_Tab, NoSymbol,
- XK_Escape, NoSymbol,
- XK_Delete, NoSymbol,
-
- XK_Home, NoSymbol,
- XK_End, NoSymbol,
- XK_Page_Up, NoSymbol,
- XK_Page_Down, NoSymbol,
- XK_Up, NoSymbol,
- XK_Down, NoSymbol,
- XK_Left, NoSymbol,
- XK_Right, NoSymbol,
-
- XK_F1, NoSymbol,
- XK_F2, NoSymbol,
- XK_F3, NoSymbol,
- XK_F4, NoSymbol,
- XK_F5, NoSymbol,
- XK_F6, NoSymbol,
- XK_F7, NoSymbol,
- XK_F8, NoSymbol,
- XK_F9, NoSymbol,
- XK_F10, NoSymbol,
- XK_F11, NoSymbol,
- XK_F12, NoSymbol,
-
- /* Plus blank ones which can be filled in using xmodmap */
-
-};
-
-#define N_PREDEFINED_KEYS (sizeof(kbdMap) / (sizeof(KeySym) * GLYPHS_PER_KEY))
-
-
-void
-PtrDeviceInit()
-{
-}
-
-
-void
-KbdDeviceInit(pDevice, pKeySyms, pModMap)
- DeviceIntPtr pDevice;
- KeySymsPtr pKeySyms;
- CARD8 *pModMap;
-{
- int i;
-
- kbdDevice = pDevice;
-
- for (i = 0; i < MAP_LENGTH; i++)
- pModMap[i] = NoSymbol;
-
- pModMap[CONTROL_L_KEY_CODE] = ControlMask;
- pModMap[CONTROL_R_KEY_CODE] = ControlMask;
- pModMap[SHIFT_L_KEY_CODE] = ShiftMask;
- pModMap[SHIFT_R_KEY_CODE] = ShiftMask;
- pModMap[META_L_KEY_CODE] = Mod1Mask;
- pModMap[META_R_KEY_CODE] = Mod1Mask;
- pModMap[ALT_L_KEY_CODE] = Mod1Mask;
- pModMap[ALT_R_KEY_CODE] = Mod1Mask;
-
- pKeySyms->minKeyCode = MIN_KEY_CODE;
- pKeySyms->maxKeyCode = MAX_KEY_CODE;
- pKeySyms->mapWidth = GLYPHS_PER_KEY;
-
- pKeySyms->map = (KeySym *)xalloc(sizeof(KeySym)
- * MAP_LENGTH * GLYPHS_PER_KEY);
-
- if (!pKeySyms->map) {
- rfbLog("xalloc failed\n");
- exit(1);
- }
-
- for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++)
- pKeySyms->map[i] = NoSymbol;
-
- for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) {
- pKeySyms->map[i] = kbdMap[i];
- }
-}
-
-
-
-void
-KbdDeviceOn()
-{
-}
-
-
-void
-KbdDeviceOff()
-{
-}
-
-
-void
-PtrDeviceOn(pDev)
- DeviceIntPtr pDev;
-{
-}
-
-
-void
-PtrDeviceOff()
-{
-}
-
-
-void
-PtrDeviceControl(dev, ctrl)
- DevicePtr dev;
- PtrCtrl *ctrl;
-{
-}
-
-
-void
-KbdAddEvent(down, keySym, cl)
- Bool down;
- KeySym keySym;
- rfbClientPtr cl;
-{
- xEvent ev, fake;
- KeySymsPtr keySyms = &kbdDevice->key->curKeySyms;
- int i;
- int keyCode = 0;
- int freeIndex = -1;
- unsigned long time;
- Bool fakeShiftPress = FALSE;
- Bool fakeShiftLRelease = FALSE;
- Bool fakeShiftRRelease = FALSE;
- Bool shiftMustBeReleased = FALSE;
- Bool shiftMustBePressed = FALSE;
-
- if (cl) {
- CARD32 clientId = cl->sock;
- ChangeWindowProperty(WindowTable[0], VNC_LAST_CLIENT_ID, XA_INTEGER,
- 32, PropModeReplace, 1, (pointer)&clientId, TRUE);
- }
-
- if (down) {
- if (rfbTrace) rfbLog("KeyPress: 0x%x\n",keySym);
- ev.u.u.type = KeyPress;
- } else {
- ev.u.u.type = KeyRelease;
- }
-
- /* First check if it's one of our predefined keys. If so then we can make
- some attempt at allowing an xmodmap inside a VNC desktop behave
- something like you'd expect - e.g. if keys A & B are swapped over and
- the VNC client sends an A, then map it to a B when generating the X
- event. We don't attempt to do this for keycodes which we make up on the
- fly because it's too hard... */
-
- for (i = 0; i < N_PREDEFINED_KEYS * GLYPHS_PER_KEY; i++) {
- if (keySym == kbdMap[i]) {
- keyCode = MIN_KEY_CODE + i / GLYPHS_PER_KEY;
-
- if (kbdMap[(i/GLYPHS_PER_KEY) * GLYPHS_PER_KEY + 1] != NoSymbol) {
-
- /* this keycode has more than one symbol associated with it,
- so shift state is important */
-
- if ((i % GLYPHS_PER_KEY) == 0)
- shiftMustBeReleased = TRUE;
- else
- shiftMustBePressed = TRUE;
- }
- break;
- }
- }
-
- if (!keyCode) {
-
- /* not one of our predefined keys - see if it's in the current keyboard
- mapping (i.e. we've already allocated an extra keycode for it) */
-
- if (keySyms->mapWidth < 2) {
- rfbLog("KbdAddEvent: Sanity check failed - Keyboard mapping has "
- "less than 2 keysyms per keycode (KeySym 0x%x)\n", keySym);
- return;
- }
-
- for (i = 0; i < NO_OF_KEYS * keySyms->mapWidth; i++) {
- if (keySym == keySyms->map[i]) {
- keyCode = MIN_KEY_CODE + i / keySyms->mapWidth;
-
- if (keySyms->map[(i / keySyms->mapWidth)
- * keySyms->mapWidth + 1] != NoSymbol) {
-
- /* this keycode has more than one symbol associated with
- it, so shift state is important */
-
- if ((i % keySyms->mapWidth) == 0)
- shiftMustBeReleased = TRUE;
- else
- shiftMustBePressed = TRUE;
- }
- break;
- }
- if ((freeIndex == -1) && (keySyms->map[i] == NoSymbol)
- && (i % keySyms->mapWidth) == 0)
- {
- freeIndex = i;
- }
- }
- }
-
- if (!keyCode) {
- KeySym lower, upper;
-
- /* we don't have an existing keycode - make one up on the fly and add
- it to the keyboard mapping. Thanks to Vlad Harchev for pointing
- out problems with non-ascii capitalisation. */
-
- if (freeIndex == -1) {
- rfbLog("KbdAddEvent: ignoring KeySym 0x%x - no free KeyCodes\n",
- keySym);
- return;
- }
-
- keyCode = MIN_KEY_CODE + freeIndex / keySyms->mapWidth;
-
- XConvertCase(keySym, &lower, &upper);
-
- if (lower == upper) {
- keySyms->map[freeIndex] = keySym;
-
- } else {
- keySyms->map[freeIndex] = lower;
- keySyms->map[freeIndex+1] = upper;
-
- if (keySym == lower)
- shiftMustBeReleased = TRUE;
- else
- shiftMustBePressed = TRUE;
- }
-
- SendMappingNotify(MappingKeyboard, keyCode, 1, serverClient);
-
- rfbLog("KbdAddEvent: unknown KeySym 0x%x - allocating KeyCode %d\n",
- keySym, keyCode);
- }
-
- time = GetTimeInMillis();
-
- if (down) {
- if (shiftMustBePressed && !(kbdDevice->key->state & ShiftMask)) {
- fakeShiftPress = TRUE;
- fake.u.u.type = KeyPress;
- fake.u.u.detail = SHIFT_L_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
- if (shiftMustBeReleased && (kbdDevice->key->state & ShiftMask)) {
- if (KEY_IS_PRESSED(SHIFT_L_KEY_CODE)) {
- fakeShiftLRelease = TRUE;
- fake.u.u.type = KeyRelease;
- fake.u.u.detail = SHIFT_L_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
- if (KEY_IS_PRESSED(SHIFT_R_KEY_CODE)) {
- fakeShiftRRelease = TRUE;
- fake.u.u.type = KeyRelease;
- fake.u.u.detail = SHIFT_R_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
- }
- }
-
- ev.u.u.detail = keyCode;
- ev.u.keyButtonPointer.time = time;
- mieqEnqueue(&ev);
-
- if (fakeShiftPress) {
- fake.u.u.type = KeyRelease;
- fake.u.u.detail = SHIFT_L_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
- if (fakeShiftLRelease) {
- fake.u.u.type = KeyPress;
- fake.u.u.detail = SHIFT_L_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
- if (fakeShiftRRelease) {
- fake.u.u.type = KeyPress;
- fake.u.u.detail = SHIFT_R_KEY_CODE;
- fake.u.keyButtonPointer.time = time;
- mieqEnqueue(&fake);
- }
-}
-
-void
-PtrAddEvent(buttonMask, x, y, cl)
- int buttonMask;
- int x;
- int y;
- rfbClientPtr cl;
-{
- xEvent ev;
- int i;
- unsigned long time;
- static int oldButtonMask = 0;
-
- if (cl) {
- CARD32 clientId = cl->sock;
- ChangeWindowProperty(WindowTable[0], VNC_LAST_CLIENT_ID, XA_INTEGER,
- 32, PropModeReplace, 1, (pointer)&clientId, TRUE);
- }
-
- time = GetTimeInMillis();
-
- miPointerAbsoluteCursor(x, y, time);
-
- for (i = 0; i < 5; i++) {
- if ((buttonMask ^ oldButtonMask) & (1<<i)) {
- if (buttonMask & (1<<i)) {
- ev.u.u.type = ButtonPress;
- ev.u.u.detail = i + 1;
- ev.u.keyButtonPointer.time = time;
- mieqEnqueue(&ev);
- } else {
- ev.u.u.type = ButtonRelease;
- ev.u.u.detail = i + 1;
- ev.u.keyButtonPointer.time = time;
- mieqEnqueue(&ev);
- }
- }
- }
-
- oldButtonMask = buttonMask;
-}
-
-void
-KbdReleaseAllKeys()
-{
- int i, j;
- xEvent ev;
- unsigned long time = GetTimeInMillis();
-
- for (i = 0; i < DOWN_LENGTH; i++) {
- if (kbdDevice->key->down[i] != 0) {
- for (j = 0; j < 8; j++) {
- if (kbdDevice->key->down[i] & (1 << j)) {
- ev.u.u.type = KeyRelease;
- ev.u.u.detail = (i << 3) | j;
- ev.u.keyButtonPointer.time = time;
- mieqEnqueue(&ev);
- }
- }
- }
- }
-}
-
-
-/* copied from Xlib source */
-
-static void XConvertCase(KeySym sym, KeySym *lower, KeySym *upper)
-{
- *lower = sym;
- *upper = sym;
- switch(sym >> 8) {
- case 0: /* Latin 1 */
- if ((sym >= XK_A) && (sym <= XK_Z))
- *lower += (XK_a - XK_A);
- else if ((sym >= XK_a) && (sym <= XK_z))
- *upper -= (XK_a - XK_A);
- else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
- *lower += (XK_agrave - XK_Agrave);
- else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
- *upper -= (XK_agrave - XK_Agrave);
- else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
- *lower += (XK_oslash - XK_Ooblique);
- else if ((sym >= XK_oslash) && (sym <= XK_thorn))
- *upper -= (XK_oslash - XK_Ooblique);
- break;
- case 1: /* Latin 2 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym == XK_Aogonek)
- *lower = XK_aogonek;
- else if (sym >= XK_Lstroke && sym <= XK_Sacute)
- *lower += (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_Scaron && sym <= XK_Zacute)
- *lower += (XK_scaron - XK_Scaron);
- else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
- *lower += (XK_zcaron - XK_Zcaron);
- else if (sym == XK_aogonek)
- *upper = XK_Aogonek;
- else if (sym >= XK_lstroke && sym <= XK_sacute)
- *upper -= (XK_lstroke - XK_Lstroke);
- else if (sym >= XK_scaron && sym <= XK_zacute)
- *upper -= (XK_scaron - XK_Scaron);
- else if (sym >= XK_zcaron && sym <= XK_zabovedot)
- *upper -= (XK_zcaron - XK_Zcaron);
- else if (sym >= XK_Racute && sym <= XK_Tcedilla)
- *lower += (XK_racute - XK_Racute);
- else if (sym >= XK_racute && sym <= XK_tcedilla)
- *upper -= (XK_racute - XK_Racute);
- break;
- case 2: /* Latin 3 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
- *lower += (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
- *lower += (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
- *upper -= (XK_hstroke - XK_Hstroke);
- else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
- *upper -= (XK_gbreve - XK_Gbreve);
- else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
- *lower += (XK_cabovedot - XK_Cabovedot);
- else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
- *upper -= (XK_cabovedot - XK_Cabovedot);
- break;
- case 3: /* Latin 4 */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Rcedilla && sym <= XK_Tslash)
- *lower += (XK_rcedilla - XK_Rcedilla);
- else if (sym >= XK_rcedilla && sym <= XK_tslash)
- *upper -= (XK_rcedilla - XK_Rcedilla);
- else if (sym == XK_ENG)
- *lower = XK_eng;
- else if (sym == XK_eng)
- *upper = XK_ENG;
- else if (sym >= XK_Amacron && sym <= XK_Umacron)
- *lower += (XK_amacron - XK_Amacron);
- else if (sym >= XK_amacron && sym <= XK_umacron)
- *upper -= (XK_amacron - XK_Amacron);
- break;
- case 6: /* Cyrillic */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
- *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
- *upper += (XK_Serbian_DJE - XK_Serbian_dje);
- else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
- *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
- else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
- *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
- break;
- case 7: /* Greek */
- /* Assume the KeySym is a legal value (ignore discontinuities) */
- if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
- *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
- sym != XK_Greek_iotaaccentdieresis &&
- sym != XK_Greek_upsilonaccentdieresis)
- *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
- else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
- *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
- else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
- sym != XK_Greek_finalsmallsigma)
- *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
- break;
- }
-}