From dc90bee2e55ddf683c925e4cd2d90de1afeaeef2 Mon Sep 17 00:00:00 2001 From: Tim Waugh Date: Jul 14 2014 16:03:58 +0000 Subject: Input reset fixes from upstream (bug #1116956). --- diff --git a/tigervnc-ext-init.patch b/tigervnc-ext-init.patch new file mode 100644 index 0000000..da52f05 --- /dev/null +++ b/tigervnc-ext-init.patch @@ -0,0 +1,20 @@ +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc~ tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc~ 2014-07-09 12:27:54.624441987 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc 2014-07-09 16:17:04.391345366 +0100 +@@ -90,9 +90,15 @@ vncSetup(pointer module, pointer opts, i + + static void vncExtensionInitWithParams(INITARGS) + { ++ static bool once = false; ++ + rfb::initStdIOLoggers(); + rfb::LogWriter::setLogParams("*:stderr:30"); +- rfb::Configuration::enableServerParams(); ++ ++ if (!once) { ++ rfb::Configuration::enableServerParams(); ++ once = true; ++ } + + for (int scr = 0; scr < screenInfo.numScreens; scr++) { + ScrnInfoPtr pScrn = xf86Screens[scr]; diff --git a/tigervnc-inputreset.patch b/tigervnc-inputreset.patch new file mode 100644 index 0000000..58b685f --- /dev/null +++ b/tigervnc-inputreset.patch @@ -0,0 +1,383 @@ +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.inputreset 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc 2014-07-14 13:08:01.482660946 +0100 +@@ -68,6 +68,9 @@ rfb::BoolParameter avoidShiftNumLock("Av + + #define BUTTONS 7 + ++class InputDevice *vncInputDevice; ++InputDevice InputDevice::singleton; ++ + /* Event queue is shared between all devices. */ + #if XORG == 15 + static xEvent *eventq = NULL; +@@ -116,11 +119,13 @@ static void enqueueEvents(DeviceIntPtr d + } + #endif /* XORG < 111 */ + +-InputDevice::InputDevice(rfb::VNCServerST *_server) +- : server(_server), initialized(false), oldButtonMask(0) ++InputDevice::InputDevice() ++ : oldButtonMask(0) + { + int i; + ++ vncInputDevice = this; ++ + #if XORG < 111 + initEventq(); + #endif +@@ -195,16 +200,12 @@ void InputDevice::PointerMove(const rfb: + cursorPos = pos; + } + +-void InputDevice::PointerSync(void) ++const rfb::Point &InputDevice::getPointerPos(void) + { +- if (cursorPos.equals(oldCursorPos)) +- return; +- +- oldCursorPos = cursorPos; +- server->setCursorPos(cursorPos); ++ return cursorPos; + } + +-static int pointerProc(DeviceIntPtr pDevice, int onoff) ++int InputDevice::pointerProc(DeviceIntPtr pDevice, int onoff) + { + BYTE map[BUTTONS + 1]; + DevicePtr pDev = (DevicePtr)pDevice; +@@ -229,6 +230,8 @@ static int pointerProc(DeviceIntPtr pDev + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); ++ btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); ++ btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); +@@ -253,10 +256,9 @@ static int pointerProc(DeviceIntPtr pDev + case DEVICE_OFF: + pDev->on = FALSE; + break; +-#if 0 + case DEVICE_CLOSE: ++ singleton.pointerDev = NULL; + break; +-#endif + } + + return Success; +@@ -269,9 +271,7 @@ static void keyboardBell(int percent, De + vncBell(); + } + +-extern void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap); +- +-static int keyboardProc(DeviceIntPtr pDevice, int onoff) ++int InputDevice::keyboardProc(DeviceIntPtr pDevice, int onoff) + { + #if XORG < 17 + KeySymsRec keySyms; +@@ -298,6 +298,9 @@ static int keyboardProc(DeviceIntPtr pDe + case DEVICE_OFF: + pDev->on = FALSE; + break; ++ case DEVICE_CLOSE: ++ singleton.keyboardDev = NULL; ++ break; + } + + return Success; +@@ -305,11 +308,9 @@ static int keyboardProc(DeviceIntPtr pDe + + void InputDevice::InitInputDevice(void) + { +- if (initialized) ++ if ((pointerDev != NULL) || (keyboardDev != NULL)) + return; + +- initialized = true; +- + #if XORG < 17 + pointerDev = AddInputDevice( + #if XORG >= 16 +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/InputCore.cc.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/InputCore.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/InputCore.cc.inputreset 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/InputCore.cc 2014-07-14 13:08:01.483660952 +0100 +@@ -174,7 +174,7 @@ KeySym keyboardMap[MAP_LEN * KEYSYMS_PER + XK_Menu, NoSymbol, + }; + +-void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap) ++void InputDevice::GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap) + { + int i; + +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/Input.h.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/Input.h +--- tigervnc-1.3.0/unix/xserver/hw/vnc/Input.h.inputreset 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/Input.h 2014-07-14 13:08:01.483660952 +0100 +@@ -29,20 +29,27 @@ + + #include + +-#include ++#include ++#include + + extern "C" { + #include "input.h" ++/* The Xorg headers define macros that wreak havoc with STL */ ++#undef max + }; + + #include "xorg-version.h" + +-/* Represents input device (keyboard + pointer) */ ++/* ++ * Represents input device (keyboard + pointer) ++ * ++ * Is a singleton as input devices are global in the X server so ++ * we do not have one per desktop (i.e. per screen). ++ */ ++extern class InputDevice *vncInputDevice; ++ + class InputDevice { + public: +- /* Create new InputDevice instance */ +- InputDevice(rfb::VNCServerST *_server); +- + /* + * Press or release buttons. Relationship between buttonMask and + * buttons is specified in RFB protocol. +@@ -52,27 +59,28 @@ public: + /* Move pointer to target location (point coords are absolute). */ + void PointerMove(const rfb::Point &point); + +- /* +- * Send pointer position to clients. If not called then Move() calls +- * won't be visible to VNC clients. +- */ +- void PointerSync(void); ++ /* Get current known location of the pointer */ ++ const rfb::Point &getPointerPos(void); + ++ /* Press or release one or more keys to get the given symbol */ + void KeyboardPress(rdr::U32 keysym) { keyEvent(keysym, true); } + void KeyboardRelease(rdr::U32 keysym) { keyEvent(keysym, false); } + + /* +- * Init input device. This cannot be done in the constructor +- * because constructor is called during X server extensions +- * initialization. Devices must be initialized after core +- * pointer/keyboard initialization which is actually after extesions +- * initialization. Check InitExtensions(), InitCoreDevices() and +- * InitInput() calls in dix/main.c. Instead it is called from +- * XserverDesktop at an appropriate time. ++ * Init input device. ++ * This has to be called after core pointer/keyboard ++ * initialization which unfortunately is after extesions ++ * initialization (which means we cannot call it in ++ * vncExtensionInit(). Check InitExtensions(), ++ * InitCoreDevices() and InitInput() calls in dix/main.c. ++ * Instead we call it from XserverDesktop at an appropriate ++ * time. + */ + void InitInputDevice(void); + + private: ++ InputDevice(); ++ + void keyEvent(rdr::U32 keysym, bool down); + + /* Backend dependent functions below here */ +@@ -96,22 +104,28 @@ private: + KeyCode addKeysym(KeySym keysym, unsigned state); + + private: ++ static int pointerProc(DeviceIntPtr pDevice, int onoff); ++ static int keyboardProc(DeviceIntPtr pDevice, int onoff); ++ + #if XORG >= 17 + static void vncXkbProcessDeviceEvent(int screenNum, + InternalEvent *event, + DeviceIntPtr dev); ++#else ++ static void GetInitKeyboardMap(KeySymsPtr keysyms, CARD8 *modmap); + #endif + + private: +- rfb::VNCServerST *server; +- bool initialized; + DeviceIntPtr keyboardDev; + DeviceIntPtr pointerDev; + + int oldButtonMask; +- rfb::Point cursorPos, oldCursorPos; ++ rfb::Point cursorPos; + + KeySym pressedKeys[256]; ++ ++private: ++ static InputDevice singleton; + }; + + #endif +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/InputXKB.cc.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/InputXKB.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/InputXKB.cc.inputreset 2014-07-14 13:07:53.145619157 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/InputXKB.cc 2014-07-14 13:08:01.484660958 +0100 +@@ -42,18 +42,6 @@ extern "C" { + #undef class + } + +-#if XORG < 19 +-static int vncXkbScreenPrivateKeyIndex; +-static DevPrivateKey vncXkbScreenPrivateKey = &vncXkbScreenPrivateKeyIndex; +-#else +-static DevPrivateKeyRec vncXkbPrivateKeyRec; +-#define vncXkbScreenPrivateKey (&vncXkbPrivateKeyRec) +-#endif +- +-#define vncXkbScreenPrivate(pScreen) \ +- (*(InputDevice**) dixLookupPrivate(&(pScreen)->devPrivates, \ +- vncXkbScreenPrivateKey)) +- + #ifndef KEYBOARD_OR_FLOAT + #define KEYBOARD_OR_FLOAT MASTER_KEYBOARD + #endif +@@ -209,18 +197,6 @@ static unsigned XkbKeyEffectiveGroup(Xkb + + void InputDevice::PrepareInputDevices(void) + { +-#if XORG < 19 +- if (!dixRequestPrivate(vncXkbScreenPrivateKey, sizeof(InputDevice*))) +- FatalError("Failed to register TigerVNC XKB screen key\n"); +-#else +- if (!dixRegisterPrivateKey(vncXkbScreenPrivateKey, PRIVATE_SCREEN, +- sizeof(InputDevice*))) +- FatalError("Failed to register TigerVNC XKB screen key\n"); +-#endif +- +- for (int scr = 0; scr < screenInfo.numScreens; scr++) +- vncXkbScreenPrivate(screenInfo.screens[scr]) = this; +- + /* + * 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 +@@ -633,10 +609,9 @@ void InputDevice::vncXkbProcessDeviceEve + InternalEvent *event, + DeviceIntPtr dev) + { +- InputDevice *self = vncXkbScreenPrivate(screenInfo.screens[screenNum]); + unsigned int backupctrls; + +- if (event->device_event.sourceid == self->keyboardDev->id) { ++ if (event->device_event.sourceid == singleton.keyboardDev->id) { + XkbControlsPtr ctrls; + + /* +@@ -658,7 +633,7 @@ void InputDevice::vncXkbProcessDeviceEve + + dev->c_public.processInputProc(event, dev); + +- if (event->device_event.sourceid == self->keyboardDev->id) { ++ if (event->device_event.sourceid == singleton.keyboardDev->id) { + XkbControlsPtr ctrls; + + ctrls = dev->key->xkbInfo->desc->ctrls; +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc.inputreset 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc 2014-07-14 13:08:01.487660972 +0100 +@@ -112,9 +112,9 @@ static void vncExtensionInitWithParams(I + i.param->setParam(val); + } + } +- +- vncExtensionInit(); + } ++ ++ vncExtensionInit(); + } + } + +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.cc.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.cc.inputreset 2014-07-14 13:07:53.140619132 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.cc 2014-07-14 13:08:01.486660967 +0100 +@@ -157,15 +157,12 @@ XserverDesktop::XserverDesktop(ScreenPtr + + if (httpListener) + httpServer = new FileHTTPServer(this); +- +- inputDevice = new InputDevice(server); + } + + XserverDesktop::~XserverDesktop() + { + if (!directFbptr) + delete [] data; +- delete inputDevice; + delete httpServer; + delete server; + } +@@ -583,7 +580,7 @@ void XserverDesktop::blockHandler(fd_set + // so we abuse the fact that this routine will be called first thing + // once the dix is done initialising. + // [1] Technically Xvnc has InitInput(), but libvnc.so has nothing. +- inputDevice->InitInputDevice(); ++ vncInputDevice->InitInputDevice(); + + try { + int nextTimeout; +@@ -691,7 +688,11 @@ void XserverDesktop::wakeupHandler(fd_se + } + } + +- inputDevice->PointerSync(); ++ // We are responsible for propagating mouse movement between clients ++ if (!oldCursorPos.equals(vncInputDevice->getPointerPos())) { ++ oldCursorPos = vncInputDevice->getPointerPos(); ++ server->setCursorPos(oldCursorPos); ++ } + } + + // Then let the timers do some processing. Rescheduling is done in +@@ -818,8 +819,8 @@ void XserverDesktop::approveConnection(v + + void XserverDesktop::pointerEvent(const Point& pos, int buttonMask) + { +- inputDevice->PointerMove(pos); +- inputDevice->PointerButtonAction(buttonMask); ++ vncInputDevice->PointerMove(pos); ++ vncInputDevice->PointerButtonAction(buttonMask); + } + + void XserverDesktop::clientCutText(const char* str, int len) +@@ -1136,7 +1137,7 @@ void XserverDesktop::lookup(int index, i + void XserverDesktop::keyEvent(rdr::U32 keysym, bool down) + { + if (down) +- inputDevice->KeyboardPress(keysym); ++ vncInputDevice->KeyboardPress(keysym); + else +- inputDevice->KeyboardRelease(keysym); ++ vncInputDevice->KeyboardRelease(keysym); + } +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.h.inputreset tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.h +--- tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.h.inputreset 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/XserverDesktop.h 2014-07-14 13:08:01.486660967 +0100 +@@ -133,7 +133,6 @@ private: + #endif + + ScreenPtr pScreen; +- InputDevice *inputDevice; + rfb::VNCServerST* server; + rfb::HTTPServer* httpServer; + network::TcpListener* listener; +@@ -153,5 +152,7 @@ private: + typedef std::map OutputIdMap; + OutputIdMap outputIdMap; + #endif ++ ++ rfb::Point oldCursorPos; + }; + #endif diff --git a/tigervnc-pointersync.patch b/tigervnc-pointersync.patch index e0d60fa..3ac8f2c 100644 --- a/tigervnc-pointersync.patch +++ b/tigervnc-pointersync.patch @@ -1,11 +1,18 @@ diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.pointersync tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc ---- tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.pointersync 2013-07-01 13:41:24.000000000 +0100 -+++ tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc 2014-05-22 11:47:16.707816457 +0100 -@@ -197,6 +197,14 @@ void InputDevice::PointerMove(const rfb: +--- tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.pointersync 2014-07-14 16:27:49.412251632 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc 2014-07-14 16:29:06.968643301 +0100 +@@ -1,5 +1,5 @@ + /* Copyright (C) 2009 TightVNC Team +- * Copyright (C) 2009 Red Hat, Inc. ++ * Copyright (C) 2009, 2014 Red Hat, Inc. + * Copyright 2013 Pierre Ossman for Cendio AB + * + * This is free software; you can redistribute it and/or modify +@@ -202,6 +202,14 @@ void InputDevice::PointerMove(const rfb: - void InputDevice::PointerSync(void) + const rfb::Point &InputDevice::getPointerPos(void) { -+ if (initialized) { ++ if (pointerDev != NULL) { + int x, y; + + GetSpritePosition (pointerDev, &x, &y); @@ -13,6 +20,6 @@ diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/Input.cc.pointersync tigervnc-1.3.0/ + cursorPos.y = y; + } + - if (cursorPos.equals(oldCursorPos)) - return; + return cursorPos; + } diff --git a/tigervnc-undo-fc23895.patch b/tigervnc-undo-fc23895.patch new file mode 100644 index 0000000..a8cd7d5 --- /dev/null +++ b/tigervnc-undo-fc23895.patch @@ -0,0 +1,48 @@ +diff -up tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc.undo-fc23895 tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc +--- tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc.undo-fc23895 2013-07-01 13:41:24.000000000 +0100 ++++ tigervnc-1.3.0/unix/xserver/hw/vnc/xf86vncModule.cc 2014-07-09 11:02:00.737066640 +0100 +@@ -90,31 +90,26 @@ vncSetup(pointer module, pointer opts, i + + static void vncExtensionInitWithParams(INITARGS) + { +- static char once = 0; ++ rfb::initStdIOLoggers(); ++ rfb::LogWriter::setLogParams("*:stderr:30"); ++ rfb::Configuration::enableServerParams(); + +- if (!once) { +- once++; +- rfb::initStdIOLoggers(); +- rfb::LogWriter::setLogParams("*:stderr:30"); +- rfb::Configuration::enableServerParams(); ++ for (int scr = 0; scr < screenInfo.numScreens; scr++) { ++ ScrnInfoPtr pScrn = xf86Screens[scr]; + +- for (int scr = 0; scr < screenInfo.numScreens; scr++) { +- ScrnInfoPtr pScrn = xf86Screens[scr]; +- +- for (ParameterIterator i; i.param; i.next()) { +- const char *val; ++ for (ParameterIterator i; i.param; i.next()) { ++ const char *val; + #if XORG < 112 +- val = xf86FindOptionValue(pScrn->options, i.param->getName()); ++ val = xf86FindOptionValue(pScrn->options, i.param->getName()); + #else +- val = xf86FindOptionValue((XF86OptionPtr)pScrn->options, i.param->getName()); ++ val = xf86FindOptionValue((XF86OptionPtr)pScrn->options, i.param->getName()); + #endif +- if (val) +- i.param->setParam(val); +- } ++ if (val) ++ i.param->setParam(val); + } +- +- vncExtensionInit(); + } ++ ++ vncExtensionInit(); + } + } + diff --git a/tigervnc.spec b/tigervnc.spec index 8c144e6..567c3be 100644 --- a/tigervnc.spec +++ b/tigervnc.spec @@ -1,6 +1,6 @@ Name: tigervnc Version: 1.3.0 -Release: 11%{?dist} +Release: 12%{?dist} Summary: A TigerVNC remote display system Group: User Interface/Desktops @@ -49,7 +49,8 @@ Patch9: tigervnc-shebang.patch Patch12: tigervnc-zrle-crash.patch Patch13: tigervnc-cursor.patch Patch14: tigervnc-CVE-2014-0011.patch -Patch15: tigervnc-pointersync.patch +Patch15: tigervnc-inputreset.patch +Patch16: tigervnc-pointersync.patch %description Virtual Network Computing (VNC) is a remote display system which @@ -181,8 +182,11 @@ popd # Fixed heap-based buffer overflow (CVE-2014-0011, bug #1050928). %patch14 -p1 -b .CVE-2014-0011 +# Input reset fixes from upstream (bug #1116956). +%patch15 -p1 -b .input-reset + # Keep pointer in sync when using module (upstream bug #152). -%patch15 -p1 -b .pointersync +%patch16 -p1 -b .pointersync %build %ifarch sparcv9 sparc64 s390 s390x @@ -352,6 +356,9 @@ fi %{_datadir}/icons/hicolor/*/apps/* %changelog +* Mon Jul 14 2014 Tim Waugh 1.3.0-12 +- Input reset fixes from upstream (bug #1116956). + * Thu May 22 2014 Tim Waugh 1.3.0-11 - Keep pointer in sync when using module (upstream bug #152).