Revision: 5120
          http://tigervnc.svn.sourceforge.net/tigervnc/?rev=5120&view=rev
Author:   ossman_
Date:     2013-05-30 14:53:40 +0000 (Thu, 30 May 2013)
Log Message:
-----------
Copy r5117 through r5119 from trunk.

Revision Links:
--------------
    http://tigervnc.svn.sourceforge.net/tigervnc/?rev=5117&view=rev
    http://tigervnc.svn.sourceforge.net/tigervnc/?rev=5119&view=rev

Modified Paths:
--------------
    branches/1_3/unix/xserver/hw/vnc/Input.cc
    branches/1_3/unix/xserver/hw/vnc/Input.h
    branches/1_3/unix/xserver/hw/vnc/InputCore.cc
    branches/1_3/unix/xserver/hw/vnc/InputXKB.cc

Modified: branches/1_3/unix/xserver/hw/vnc/Input.cc
===================================================================
--- branches/1_3/unix/xserver/hw/vnc/Input.cc   2013-05-30 14:50:57 UTC (rev 
5119)
+++ branches/1_3/unix/xserver/hw/vnc/Input.cc   2013-05-30 14:53:40 UTC (rev 
5120)
@@ -64,6 +64,8 @@
 
 static LogWriter vlog("Input");
 
+rfb::BoolParameter avoidShiftNumLock("AvoidShiftNumLock", "Avoid fake Shift 
presses for keys affected by NumLock.", true);
+
 #define BUTTONS 7
 
 /* Event queue is shared between all devices. */
@@ -475,18 +477,18 @@
        /* Try some equivalent keysyms if we couldn't find a perfect match */
        if (keycode == 0) {
                for (i = 0;i < sizeof(altKeysym)/sizeof(altKeysym[0]);i++) {
-                       if (altKeysym[i].a == keysym) {
-                               keycode = keysymToKeycode(altKeysym[i].b,
-                                                         state, &new_state);
-                               if (keycode != 0)
-                                       break;
-                       }
-                       if (altKeysym[i].b == keysym) {
-                               keycode = keysymToKeycode(altKeysym[i].a,
-                                                         state, &new_state);
-                               if (keycode != 0)
-                                       break;
-                       }
+                       KeySym altsym;
+
+                       if (altKeysym[i].a == keysym)
+                               altsym = altKeysym[i].b;
+                       else if (altKeysym[i].b == keysym)
+                               altsym = altKeysym[i].a;
+                       else
+                               continue;
+
+                       keycode = keysymToKeycode(altsym, state, &new_state);
+                       if (keycode != 0)
+                               break;
                }
        }
 
@@ -520,6 +522,53 @@
        }
 
        /*
+        * X11 generally lets shift toggle the keys on the numeric pad
+        * the same way NumLock does. This is however not the case on
+        * other systems like Windows. As a result, some applications
+        * get confused when we do a fake shift to get the same effect
+        * that having NumLock active would produce.
+        *
+        * Until we have proper NumLock synchronisation (so we can
+        * avoid faking shift), we try to avoid the fake shifts if we
+        * can use an alternative keysym.
+        */
+       if (((state & ShiftMask) != (new_state & ShiftMask)) &&
+           avoidShiftNumLock && isAffectedByNumLock(keycode)) {
+               KeyCode keycode2;
+               unsigned new_state2;
+
+               vlog.debug("Finding alternative to keysym 0x%x to avoid fake 
shift for numpad", keysym);
+
+               for (i = 0;i < sizeof(altKeysym)/sizeof(altKeysym[0]);i++) {
+                       KeySym altsym;
+
+                       if (altKeysym[i].a == keysym)
+                               altsym = altKeysym[i].b;
+                       else if (altKeysym[i].b == keysym)
+                               altsym = altKeysym[i].a;
+                       else
+                               continue;
+
+                       keycode2 = keysymToKeycode(altsym, state, &new_state2);
+                       if (keycode2 == 0)
+                               continue;
+
+                       if (((state & ShiftMask) != (new_state2 & ShiftMask)) &&
+                           isAffectedByNumLock(keycode2))
+                               continue;
+
+                       break;
+               }
+
+               if (i == sizeof(altKeysym)/sizeof(altKeysym[0]))
+                       vlog.debug("No alternative keysym found");
+               else {
+                       keycode = keycode2;
+                       new_state = new_state2;
+               }
+       }
+
+       /*
         * "Shifted Tab" is a bit of a mess. Some systems have varying,
         * special keysyms for this symbol. VNC mandates that clients
         * should always send the plain XK_Tab keysym and the server

Modified: branches/1_3/unix/xserver/hw/vnc/Input.h
===================================================================
--- branches/1_3/unix/xserver/hw/vnc/Input.h    2013-05-30 14:50:57 UTC (rev 
5119)
+++ branches/1_3/unix/xserver/hw/vnc/Input.h    2013-05-30 14:53:40 UTC (rev 
5120)
@@ -91,6 +91,8 @@
 
        bool isLockModifier(KeyCode keycode, unsigned state);
 
+       bool isAffectedByNumLock(KeyCode keycode);
+
        KeyCode addKeysym(KeySym keysym, unsigned state);
 
 private:

Modified: branches/1_3/unix/xserver/hw/vnc/InputCore.cc
===================================================================
--- branches/1_3/unix/xserver/hw/vnc/InputCore.cc       2013-05-30 14:50:57 UTC 
(rev 5119)
+++ branches/1_3/unix/xserver/hw/vnc/InputCore.cc       2013-05-30 14:53:40 UTC 
(rev 5120)
@@ -514,6 +514,26 @@
        return false;
 }
 
+bool InputDevice::isAffectedByNumLock(KeyCode keycode)
+{
+       KeySymsPtr keymap;
+       int i, per;
+       KeySym *syms;
+
+       keymap = &keyboardDev->key->curKeySyms;
+       per = keymap->mapWidth;
+       syms = &keymap->map[(keycode - keymap->minKeyCode) * per];
+
+       for (i = 0;i < per;i++) {
+               if (IsKeypadKey(syms[i]))
+                       return true;
+               if (IsPrivateKeypadKey(syms[i]))
+                       return true;
+       }
+
+       return false;
+}
+
 KeyCode InputDevice::addKeysym(KeySym keysym, unsigned state)
 {
        KeyCode kc;

Modified: branches/1_3/unix/xserver/hw/vnc/InputXKB.cc
===================================================================
--- branches/1_3/unix/xserver/hw/vnc/InputXKB.cc        2013-05-30 14:50:57 UTC 
(rev 5119)
+++ branches/1_3/unix/xserver/hw/vnc/InputXKB.cc        2013-05-30 14:53:40 UTC 
(rev 5120)
@@ -177,6 +177,36 @@
        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)
 {
 #if XORG < 19
@@ -210,20 +240,25 @@
 
 unsigned InputDevice::getLevelThreeMask(void)
 {
+       unsigned state;
        KeyCode keycode;
        XkbDescPtr xkb;
        XkbAction *act;
 
-       keycode = keysymToKeycode(XK_ISO_Level3_Shift, 0, NULL);
+       /* 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, 0, NULL);
+               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, 0);
+       act = XkbKeyActionPtr(xkb, keycode, state);
        if (act == NULL)
                return 0;
        if (act->type != XkbSA_SetMods)
@@ -338,7 +373,7 @@
 
        xkb = GetMaster(keyboardDev, KEYBOARD_OR_FLOAT)->key->xkbInfo->desc;
 
-       act = XkbKeyActionPtr(xkb, keycode, 0);
+       act = XkbKeyActionPtr(xkb, keycode, state);
        if (act == NULL)
                return 0;
        if (act->type != XkbSA_SetMods)
@@ -474,6 +509,53 @@
        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;

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Tigervnc-commits mailing list
Tigervnc-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-commits

Reply via email to