From 03bf2457002129d38027e0a9a849f3e651120255 Mon Sep 17 00:00:00 2001 From: Adam Tkac Date: Fri, 14 Jan 2011 13:40:35 +0100 Subject: [PATCH] Attempt to fix various keyboard-related issues (key repeating etc). Signed-off-by: Adam Tkac --- tigervnc.spec | 10 ++- tigervnc11-rh607866.patch | 156 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 tigervnc11-rh607866.patch diff --git a/tigervnc.spec b/tigervnc.spec index 14f9d97..0b279d6 100644 --- a/tigervnc.spec +++ b/tigervnc.spec @@ -2,7 +2,7 @@ Name: tigervnc Version: 1.0.90 -Release: 0.27.%{snap}%{?dist} +Release: 0.28.%{snap}%{?dist} Summary: A TigerVNC remote display system Group: User Interface/Desktops @@ -44,6 +44,7 @@ Patch4: tigervnc-cookie.patch Patch8: tigervnc-viewer-reparent.patch Patch10: tigervnc11-ldnow.patch Patch11: tigervnc11-optionsdialog.patch +Patch12: tigervnc11-rh607866.patch %description Virtual Network Computing (VNC) is a remote display system which @@ -132,6 +133,7 @@ This package contains license of the TigerVNC suite pushd unix/vncviewer %patch11 -p0 -b .optionsdialog popd +%patch12 -p1 -b .rh607866 cp -r /usr/share/xorg-x11-server-source/* unix/xserver pushd unix/xserver @@ -170,7 +172,8 @@ autoreconf -fiv --disable-config-dbus \ --disable-config-hal \ --disable-config-udev \ - --with-dri-driver-path=%{_libdir}/dri + --with-dri-driver-path=%{_libdir}/dri \ + --without-dtrace make %{?_smp_mflags} popd @@ -300,6 +303,9 @@ fi %doc LICENCE.TXT %changelog +* Fri Jan 14 2011 Adam Tkac 1.0.90-0.28.20101208svn4225 +- attempt to fix various keyboard-related issues (key repeating etc) + * Fri Jan 07 2011 Adam Tkac 1.0.90-0.27.20101208svn4225 - render "Ok" and "Cancel" buttons in the options dialog correctly diff --git a/tigervnc11-rh607866.patch b/tigervnc11-rh607866.patch new file mode 100644 index 0000000..6689248 --- /dev/null +++ b/tigervnc11-rh607866.patch @@ -0,0 +1,156 @@ +diff -up tigervnc-1.0.90-20101208svn4225/unix/xserver/hw/vnc/Input.cc.rh607866 tigervnc-1.0.90-20101208svn4225/unix/xserver/hw/vnc/Input.cc +--- tigervnc-1.0.90-20101208svn4225/unix/xserver/hw/vnc/Input.cc.rh607866 2011-01-14 13:11:34.133210830 +0100 ++++ tigervnc-1.0.90-20101208svn4225/unix/xserver/hw/vnc/Input.cc 2011-01-14 13:14:56.744795691 +0100 +@@ -520,6 +520,49 @@ static struct altKeysym_t { + #define FREE_MAPS + #endif + ++#if XORG >= 17 ++/* ++ * Modifier keysyms must be handled differently. Instead of finding ++ * the right row and collumn in the keymap, directly press/release ++ * the keycode which is mapped as modifier with the same keysym. ++ * ++ * This will avoid issues when there are multiple modifier keysyms ++ * in the keymap but only some of them are mapped as modifiers in ++ * the modmap. ++ * ++ * Returns keycode of the modifier key. ++ */ ++ ++static inline int isModifier(KeySymsPtr keymap, KeyCode *modmap, ++ int maxKeysPerMod, rdr::U32 keysym) ++{ ++ KeySym *map = keymap->map; ++ KeyCode minKeyCode = keymap->minKeyCode; ++ int mapWidth = keymap->mapWidth; ++ int i, j, k; ++ ++ /* Find modifier index in the modmap */ ++ for (i = 0; i < 8; i++) { ++ for (k = 0; k < maxKeysPerMod; k++) { ++ int index = i * maxKeysPerMod + k; ++ int keycode = modmap[index]; ++ ++ if (keycode == 0) ++ continue; ++ ++ for (j = 0; j < mapWidth; j++) { ++ if (map[(keycode - minKeyCode) * mapWidth + j] ++ == keysym) { ++ return keycode; ++ } ++ } ++ } ++ } ++ ++ return -1; /* Not a modifier */ ++} ++#endif ++ + void InputDevice::keyEvent(rdr::U32 keysym, bool down) + { + #if XORG < 17 +@@ -533,6 +576,9 @@ void InputDevice::keyEvent(rdr::U32 keys + int mapWidth; + unsigned int i; + int j, k, state, maxKeysPerMod; ++#if XORG >= 18 ++ KeybdCtrl ctrl; ++#endif + + initInputDevice(); + +@@ -582,6 +628,18 @@ void InputDevice::keyEvent(rdr::U32 keys + maxKeyCode = keymap->maxKeyCode; + mapWidth = keymap->mapWidth; + ++#if XORG >= 18 ++ /* ++ * No server-side key repeating, please. Some clients won't work well, ++ * check https://bugzilla.redhat.com/show_bug.cgi?id=607866. ++ */ ++ ctrl = keyboardDev->kbdfeed->ctrl; ++ if (ctrl.autoRepeat != FALSE) { ++ ctrl.autoRepeat = FALSE; ++ XkbSetRepeatKeys(keyboardDev, -1, ctrl.autoRepeat); ++ } ++#endif ++ + /* find which modifier Mode_switch is on. */ + int modeSwitchMapIndex = 0; + for (i = 3; i < 8; i++) { +@@ -603,7 +661,36 @@ void InputDevice::keyEvent(rdr::U32 keys + } + ModeSwitchFound: + ++ int kc; + int col = 0; ++ ++#if XORG >= 17 ++ if ((kc = isModifier(keymap, modmap, maxKeysPerMod, keysym)) != -1) { ++ /* ++ * It is a modifier key event. ++ * ++ * Don't do any auto-repeat because the X server will translate ++ * each press into a release followed by a press. ++ */ ++ if (IS_PRESSED(keyc, kc) && down) { ++ FREE_MAPS; ++ return; ++ } ++ ++ goto press; ++ } else { ++ /* ++ * If you would like to press a key which is already pressed then ++ * viewer didn't send the "release" event. In this case release it ++ * before the press. ++ */ ++ if (IS_PRESSED(keyc, kc) && down) { ++ vlog.debug("KeyRelease for %d wasn't sent, releasing", kc); ++ pressKey(keyboardDev, kc, KeyRelease, "fixing keycode"); ++ } ++ } ++#endif ++ + if (maxKeysPerMod != 0) { + if ((state & (1 << ShiftMapIndex)) != 0) + col |= 1; +@@ -612,7 +699,7 @@ ModeSwitchFound: + col |= 2; + } + +- int kc = KeysymToKeycode(keymap, keysym, &col); ++ kc = KeysymToKeycode(keymap, keysym, &col); + + /* + * Sort out the "shifted Tab" mess. If we are sent a shifted Tab, +@@ -689,6 +776,7 @@ ModeSwitchFound: + return; + } + ++#if XORG < 17 + /* + * See if it's a modifier key. If so, then don't do any auto-repeat, + * because the X server will translate each press into a release +@@ -703,6 +791,7 @@ ModeSwitchFound: + } + } + } ++#endif + + if (maxKeysPerMod != 0) { + ModifierState shift(keyboardDev, ShiftMapIndex); +@@ -724,8 +813,10 @@ ModeSwitchFound: + * pressKey call, otherwise fake modifier keypress can be lost. + */ + pressKey(keyboardDev, kc, down, "keycode"); +- } else ++ } else { ++press: + pressKey(keyboardDev, kc, down, "keycode"); ++ } + + + FREE_MAPS;