aboutsummaryrefslogtreecommitdiffstats
path: root/unix/xserver/hw/vnc/InputXKB.cc
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2015-01-26 14:37:04 +0100
committerPierre Ossman <ossman@cendio.se>2015-01-26 15:14:33 +0100
commitf8e3b34c69b848781b958c7a4d21175ddc6f90d8 (patch)
treef2aec3ca936379cd910099f4be94a1e023ae4e88 /unix/xserver/hw/vnc/InputXKB.cc
parentcc3179046eb9b0a5e9f27572de1195ac8acf4766 (diff)
downloadtigervnc-f8e3b34c69b848781b958c7a4d21175ddc6f90d8.tar.gz
tigervnc-f8e3b34c69b848781b958c7a4d21175ddc6f90d8.zip
Restructure Xvnc/libvnc.so code to avoid C++ header hacks
The internal Xorg headers are very incompatible with C++ and we've had to resort to all kinds of hacks in order to include them in our C++ code. This approach isn't really viable long term so restructure things so that we have a glue layer written in C that bridges the Xorg core with the RFB classes.
Diffstat (limited to 'unix/xserver/hw/vnc/InputXKB.cc')
-rw-r--r--unix/xserver/hw/vnc/InputXKB.cc647
1 files changed, 0 insertions, 647 deletions
diff --git a/unix/xserver/hw/vnc/InputXKB.cc b/unix/xserver/hw/vnc/InputXKB.cc
deleted file mode 100644
index 92288aa4..00000000
--- a/unix/xserver/hw/vnc/InputXKB.cc
+++ /dev/null
@@ -1,647 +0,0 @@
-/* Copyright (C) 2009 TightVNC Team
- * Copyright (C) 2009 Red Hat, Inc.
- * Copyright 2013 Pierre Ossman for Cendio AB
- *
- * 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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "Input.h"
-#include "xorg-version.h"
-
-#if XORG >= 17
-
-extern "C" {
-#define public c_public
-#define class c_class
-#include "xkbsrv.h"
-#include "xkbstr.h"
-#include "eventstr.h"
-#include "scrnintstr.h"
-#include "mi.h"
-#include <X11/keysym.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#undef public
-#undef class
-}
-
-#ifndef KEYBOARD_OR_FLOAT
-#define KEYBOARD_OR_FLOAT MASTER_KEYBOARD
-#endif
-
-/* Stolen from libX11 */
-static Bool
-XkbTranslateKeyCode(register XkbDescPtr xkb, KeyCode key,
- register unsigned int mods, unsigned int *mods_rtrn,
- KeySym *keysym_rtrn)
-{
- XkbKeyTypeRec *type;
- int col,nKeyGroups;
- unsigned preserve,effectiveGroup;
- KeySym *syms;
-
- if (mods_rtrn!=NULL)
- *mods_rtrn = 0;
-
- nKeyGroups= XkbKeyNumGroups(xkb,key);
- if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0)) {
- if (keysym_rtrn!=NULL)
- *keysym_rtrn = NoSymbol;
- return False;
- }
-
- syms = XkbKeySymsPtr(xkb,key);
-
- /* find the offset of the effective group */
- col = 0;
- effectiveGroup= XkbGroupForCoreState(mods);
- if ( effectiveGroup>=nKeyGroups ) {
- unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
- switch (XkbOutOfRangeGroupAction(groupInfo)) {
- default:
- effectiveGroup %= nKeyGroups;
- break;
- case XkbClampIntoRange:
- effectiveGroup = nKeyGroups-1;
- break;
- case XkbRedirectIntoRange:
- effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
- if (effectiveGroup>=nKeyGroups)
- effectiveGroup= 0;
- break;
- }
- }
- col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
- type = XkbKeyKeyType(xkb,key,effectiveGroup);
-
- preserve= 0;
- if (type->map) { /* find the column (shift level) within the group */
- register int i;
- register XkbKTMapEntryPtr entry;
- for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
- if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
- col+= entry->level;
- if (type->preserve)
- preserve= type->preserve[i].mask;
- break;
- }
- }
- }
-
- if (keysym_rtrn!=NULL)
- *keysym_rtrn= syms[col];
- if (mods_rtrn)
- *mods_rtrn= type->mods.mask&(~preserve);
-
- return (syms[col]!=NoSymbol);
-}
-
-static XkbAction *XkbKeyActionPtr(XkbDescPtr xkb, KeyCode key, unsigned int mods)
-{
- XkbKeyTypeRec *type;
- int col,nKeyGroups;
- unsigned effectiveGroup;
- XkbAction *acts;
-
- if (!XkbKeyHasActions(xkb, key))
- return NULL;
-
- nKeyGroups= XkbKeyNumGroups(xkb,key);
- if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0))
- return NULL;
-
- acts = XkbKeyActionsPtr(xkb,key);
-
- /* find the offset of the effective group */
- col = 0;
- effectiveGroup= XkbGroupForCoreState(mods);
- if ( effectiveGroup>=nKeyGroups ) {
- unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
- switch (XkbOutOfRangeGroupAction(groupInfo)) {
- default:
- effectiveGroup %= nKeyGroups;
- break;
- case XkbClampIntoRange:
- effectiveGroup = nKeyGroups-1;
- break;
- case XkbRedirectIntoRange:
- effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
- if (effectiveGroup>=nKeyGroups)
- effectiveGroup= 0;
- break;
- }
- }
- col= effectiveGroup*XkbKeyGroupsWidth(xkb,key);
- type = XkbKeyKeyType(xkb,key,effectiveGroup);
-
- if (type->map) { /* find the column (shift level) within the group */
- register int i;
- register XkbKTMapEntryPtr entry;
- for (i=0,entry=type->map;i<type->map_count;i++,entry++) {
- if ((entry->active)&&((mods&type->mods.mask)==entry->mods.mask)) {
- col+= entry->level;
- break;
- }
- }
- }
-
- return &acts[col];
-}
-
-static unsigned XkbKeyEffectiveGroup(XkbDescPtr xkb, KeyCode key, unsigned int mods)
-{
- int nKeyGroups;
- unsigned effectiveGroup;
-
- nKeyGroups= XkbKeyNumGroups(xkb,key);
- if ((!XkbKeycodeInRange(xkb,key))||(nKeyGroups==0))
- return 0;
-
- effectiveGroup= XkbGroupForCoreState(mods);
- if ( effectiveGroup>=nKeyGroups ) {
- unsigned groupInfo= XkbKeyGroupInfo(xkb,key);
- switch (XkbOutOfRangeGroupAction(groupInfo)) {
- default:
- effectiveGroup %= nKeyGroups;
- break;
- case XkbClampIntoRange:
- effectiveGroup = nKeyGroups-1;
- break;
- case XkbRedirectIntoRange:
- effectiveGroup = XkbOutOfRangeGroupNumber(groupInfo);
- if (effectiveGroup>=nKeyGroups)
- effectiveGroup= 0;
- break;
- }
- }
-
- return effectiveGroup;
-}
-
-void InputDevice::PrepareInputDevices(void)
-{
- /*
- * Not ideal since these callbacks do not stack, but it's the only
- * decent way we can reliably catch events for both the slave and
- * master device.
- */
- mieqSetHandler(ET_KeyPress, vncXkbProcessDeviceEvent);
- mieqSetHandler(ET_KeyRelease, vncXkbProcessDeviceEvent);
-}
-
-unsigned InputDevice::getKeyboardState(void)
-{
- DeviceIntPtr master;
-
- master = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT);
- return XkbStateFieldFromRec(&master->key->xkbInfo->state);
-}
-
-unsigned InputDevice::getLevelThreeMask(void)
-{
- unsigned state;
- KeyCode keycode;
- XkbDescPtr xkb;
- XkbAction *act;
-
- /* Group state is still important */
- state = getKeyboardState();
- state &= ~0xff;
-
- keycode = keysymToKeycode(XK_ISO_Level3_Shift, state, NULL);
- if (keycode == 0) {
- keycode = keysymToKeycode(XK_Mode_switch, state, NULL);
- if (keycode == 0)
- return 0;
- }
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
-
- act = XkbKeyActionPtr(xkb, keycode, state);
- if (act == NULL)
- return 0;
- if (act->type != XkbSA_SetMods)
- return 0;
-
- if (act->mods.flags & XkbSA_UseModMapMods)
- return xkb->map->modmap[keycode];
- else
- return act->mods.mask;
-}
-
-KeyCode InputDevice::pressShift(void)
-{
- unsigned state;
-
- XkbDescPtr xkb;
- unsigned int key;
-
- state = getKeyboardState();
- if (state & ShiftMask)
- return 0;
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
- for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) {
- XkbAction *act;
- unsigned char mask;
-
- act = XkbKeyActionPtr(xkb, key, state);
- if (act == NULL)
- continue;
-
- if (act->type != XkbSA_SetMods)
- continue;
-
- if (act->mods.flags & XkbSA_UseModMapMods)
- mask = xkb->map->modmap[key];
- else
- mask = act->mods.mask;
-
- if ((mask & ShiftMask) == ShiftMask)
- return key;
- }
-
- return 0;
-}
-
-std::list<KeyCode> InputDevice::releaseShift(void)
-{
- unsigned state;
- std::list<KeyCode> keys;
-
- DeviceIntPtr master;
- XkbDescPtr xkb;
- unsigned int key;
-
- state = getKeyboardState();
- if (!(state & ShiftMask))
- return keys;
-
- master = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT);
- xkb = master->key->xkbInfo->desc;
- for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) {
- XkbAction *act;
- unsigned char mask;
-
- if (!key_is_down(master, key, KEY_PROCESSED))
- continue;
-
- act = XkbKeyActionPtr(xkb, key, state);
- if (act == NULL)
- continue;
-
- if (act->type != XkbSA_SetMods)
- continue;
-
- if (act->mods.flags & XkbSA_UseModMapMods)
- mask = xkb->map->modmap[key];
- else
- mask = act->mods.mask;
-
- if (!(mask & ShiftMask))
- continue;
-
- keys.push_back(key);
- }
-
- return keys;
-}
-
-KeyCode InputDevice::pressLevelThree(void)
-{
- unsigned state, mask;
-
- KeyCode keycode;
- XkbDescPtr xkb;
- XkbAction *act;
-
- mask = getLevelThreeMask();
- if (mask == 0)
- return 0;
-
- state = getKeyboardState();
- if (state & mask)
- return 0;
-
- keycode = keysymToKeycode(XK_ISO_Level3_Shift, state, NULL);
- if (keycode == 0) {
- keycode = keysymToKeycode(XK_Mode_switch, state, NULL);
- if (keycode == 0)
- return 0;
- }
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
-
- act = XkbKeyActionPtr(xkb, keycode, state);
- if (act == NULL)
- return 0;
- if (act->type != XkbSA_SetMods)
- return 0;
-
- return keycode;
-}
-
-std::list<KeyCode> InputDevice::releaseLevelThree(void)
-{
- unsigned state, mask;
- std::list<KeyCode> keys;
-
- DeviceIntPtr master;
- XkbDescPtr xkb;
- unsigned int key;
-
- mask = getLevelThreeMask();
- if (mask == 0)
- return keys;
-
- state = getKeyboardState();
- if (!(state & mask))
- return keys;
-
- master = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT);
- xkb = master->key->xkbInfo->desc;
- for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) {
- XkbAction *act;
- unsigned char key_mask;
-
- if (!key_is_down(master, key, KEY_PROCESSED))
- continue;
-
- act = XkbKeyActionPtr(xkb, key, state);
- if (act == NULL)
- continue;
-
- if (act->type != XkbSA_SetMods)
- continue;
-
- if (act->mods.flags & XkbSA_UseModMapMods)
- key_mask = xkb->map->modmap[key];
- else
- key_mask = act->mods.mask;
-
- if (!(key_mask & mask))
- continue;
-
- keys.push_back(key);
- }
-
- return keys;
-}
-
-KeyCode InputDevice::keysymToKeycode(KeySym keysym, unsigned state,
- unsigned *new_state)
-{
- XkbDescPtr xkb;
- unsigned int key;
- KeySym ks;
- unsigned level_three_mask;
-
- if (new_state != NULL)
- *new_state = state;
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
- for (key = xkb->min_key_code; key <= xkb->max_key_code; key++) {
- unsigned int state_out;
- KeySym dummy;
-
- XkbTranslateKeyCode(xkb, key, state, &state_out, &ks);
- if (ks == NoSymbol)
- continue;
-
- /*
- * Despite every known piece of documentation on
- * XkbTranslateKeyCode() stating that mods_rtrn returns
- * the unconsumed modifiers, in reality it always
- * returns the _potentially consumed_ modifiers.
- */
- state_out = state & ~state_out;
- if (state_out & LockMask)
- XkbConvertCase(ks, &dummy, &ks);
-
- if (ks == keysym)
- return key;
- }
-
- if (new_state == NULL)
- return 0;
-
- *new_state = (state & ~ShiftMask) |
- ((state & ShiftMask) ? 0 : ShiftMask);
- key = keysymToKeycode(keysym, *new_state, NULL);
- if (key != 0)
- return key;
-
- level_three_mask = getLevelThreeMask();
- if (level_three_mask == 0)
- return 0;
-
- *new_state = (state & ~level_three_mask) |
- ((state & level_three_mask) ? 0 : level_three_mask);
- key = keysymToKeycode(keysym, *new_state, NULL);
- if (key != 0)
- return key;
-
- *new_state = (state & ~(ShiftMask | level_three_mask)) |
- ((state & ShiftMask) ? 0 : ShiftMask) |
- ((state & level_three_mask) ? 0 : level_three_mask);
- key = keysymToKeycode(keysym, *new_state, NULL);
- if (key != 0)
- return key;
-
- return 0;
-}
-
-bool InputDevice::isLockModifier(KeyCode keycode, unsigned state)
-{
- XkbDescPtr xkb;
- XkbAction *act;
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
-
- act = XkbKeyActionPtr(xkb, keycode, state);
- if (act == NULL)
- return false;
-
- if (act->type != XkbSA_LockMods)
- return false;
-
- return true;
-}
-
-bool InputDevice::isAffectedByNumLock(KeyCode keycode)
-{
- unsigned state;
-
- KeyCode numlock_keycode;
- unsigned numlock_mask;
-
- XkbDescPtr xkb;
- XkbAction *act;
-
- unsigned group;
- XkbKeyTypeRec *type;
-
- /* Group state is still important */
- state = getKeyboardState();
- state &= ~0xff;
-
- /*
- * Not sure if hunting for a virtual modifier called "NumLock",
- * or following the keysym Num_Lock is the best approach. We
- * try the latter.
- */
- numlock_keycode = keysymToKeycode(XK_Num_Lock, state, NULL);
- if (numlock_keycode == 0)
- return false;
-
- xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
-
- act = XkbKeyActionPtr(xkb, numlock_keycode, state);
- if (act == NULL)
- return false;
- if (act->type != XkbSA_LockMods)
- return false;
-
- if (act->mods.flags & XkbSA_UseModMapMods)
- numlock_mask = xkb->map->modmap[keycode];
- else
- numlock_mask = act->mods.mask;
-
- group = XkbKeyEffectiveGroup(xkb, keycode, state);
- type = XkbKeyKeyType(xkb, keycode, group);
- if ((type->mods.mask & numlock_mask) == 0)
- return false;
-
- return true;
-}
-
-KeyCode InputDevice::addKeysym(KeySym keysym, unsigned state)
-{
- DeviceIntPtr master;
- XkbDescPtr xkb;
- unsigned int key;
-
- XkbEventCauseRec cause;
- XkbChangesRec changes;
-
- int types[1];
- KeySym *syms;
- KeySym upper, lower;
-
- master = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT);
- xkb = master->key->xkbInfo->desc;
- for (key = xkb->max_key_code; key >= xkb->min_key_code; key--) {
- if (XkbKeyNumGroups(xkb, key) == 0)
- break;
- }
-
- if (key < xkb->min_key_code)
- return 0;
-
- memset(&changes, 0, sizeof(changes));
- memset(&cause, 0, sizeof(cause));
-
- XkbSetCauseUnknown(&cause);
-
- /*
- * Tools like xkbcomp get confused if there isn't a name
- * assigned to the keycode we're trying to use.
- */
- if (xkb->names && xkb->names->keys &&
- (xkb->names->keys[key].name[0] == '\0')) {
- xkb->names->keys[key].name[0] = 'I';
- xkb->names->keys[key].name[1] = '0' + (key / 100) % 10;
- xkb->names->keys[key].name[2] = '0' + (key / 10) % 10;
- xkb->names->keys[key].name[3] = '0' + (key / 1) % 10;
-
- changes.names.changed |= XkbKeyNamesMask;
- changes.names.first_key = key;
- changes.names.num_keys = 1;
- }
-
- /* FIXME: Verify that ONE_LEVEL/ALPHABETIC isn't screwed up */
-
- /*
- * For keysyms that are affected by Lock, we are better off
- * using ALPHABETIC rather than ONE_LEVEL as the latter
- * generally cannot produce lower case when Lock is active.
- */
- XkbConvertCase(keysym, &lower, &upper);
- if (upper == lower)
- types[XkbGroup1Index] = XkbOneLevelIndex;
- else
- types[XkbGroup1Index] = XkbAlphabeticIndex;
-
- XkbChangeTypesOfKey(xkb, key, 1, XkbGroup1Mask, types, &changes.map);
-
- syms = XkbKeySymsPtr(xkb,key);
- if (upper == lower)
- syms[0] = keysym;
- else {
- syms[0] = lower;
- syms[1] = upper;
- }
-
- changes.map.changed |= XkbKeySymsMask;
- changes.map.first_key_sym = key;
- changes.map.num_key_syms = 1;
-
- XkbSendNotification(master, &changes, &cause);
-
- return key;
-}
-
-void InputDevice::vncXkbProcessDeviceEvent(int screenNum,
- InternalEvent *event,
- DeviceIntPtr dev)
-{
- unsigned int backupctrls;
-
- if (event->device_event.sourceid == singleton.keyboardDev->id) {
- XkbControlsPtr ctrls;
-
- /*
- * We need to bypass AccessX since it is timing sensitive and
- * the network can cause fake event delays.
- */
- ctrls = dev->key->xkbInfo->desc->ctrls;
- backupctrls = ctrls->enabled_ctrls;
- ctrls->enabled_ctrls &= ~XkbAllFilteredEventsMask;
-
- /*
- * This flag needs to be set for key repeats to be properly
- * respected.
- */
- if ((event->device_event.type == ET_KeyPress) &&
- key_is_down(dev, event->device_event.detail.key, KEY_PROCESSED))
- event->device_event.key_repeat = TRUE;
- }
-
- dev->c_public.processInputProc(event, dev);
-
- if (event->device_event.sourceid == singleton.keyboardDev->id) {
- XkbControlsPtr ctrls;
-
- ctrls = dev->key->xkbInfo->desc->ctrls;
- ctrls->enabled_ctrls = backupctrls;
- }
-}
-
-#endif /* XORG >= 117 */