diff --git a/unix/x0vncserver/XDesktop.cxx b/unix/x0vncserver/XDesktop.cxx
index 7123d74..748796b 100644
--- a/unix/x0vncserver/XDesktop.cxx
+++ b/unix/x0vncserver/XDesktop.cxx
@@ -56,275 +56,275 @@
 };
 
 XDesktop::XDesktop(Display* dpy_, Geometry *geometry_)
-    : dpy(dpy_), geometry(geometry_), pb(0), server(0),
-      oldButtonMask(0), haveXtest(false), haveDamage(false),
-      maxButtons(0), running(false), ledMasks(), ledState(0),
-      codeMap(0), codeMapLen(0)
+  : dpy(dpy_), geometry(geometry_), pb(0), server(0),
+    oldButtonMask(0), haveXtest(false), haveDamage(false),
+    maxButtons(0), running(false), ledMasks(), ledState(0),
+    codeMap(0), codeMapLen(0)
 {
-    int major, minor;
+  int major, minor;
 
-    int xkbOpcode, xkbErrorBase;
+  int xkbOpcode, xkbErrorBase;
 
-    major = XkbMajorVersion;
-    minor = XkbMinorVersion;
-    if (!XkbQueryExtension(dpy, &xkbOpcode, &xkbEventBase,
-                           &xkbErrorBase, &major, &minor)) {
-      vlog.error("XKEYBOARD extension not present");
-      throw Exception();
-    }
+  major = XkbMajorVersion;
+  minor = XkbMinorVersion;
+  if (!XkbQueryExtension(dpy, &xkbOpcode, &xkbEventBase,
+                         &xkbErrorBase, &major, &minor)) {
+    vlog.error("XKEYBOARD extension not present");
+    throw Exception();
+  }
 
-    XkbSelectEvents(dpy, XkbUseCoreKbd, XkbIndicatorStateNotifyMask,
-                    XkbIndicatorStateNotifyMask);
+  XkbSelectEvents(dpy, XkbUseCoreKbd, XkbIndicatorStateNotifyMask,
+                  XkbIndicatorStateNotifyMask);
 
-    // figure out bit masks for the indicators we are interested in
-    for (int i = 0; i < XDESKTOP_N_LEDS; i++) {
-      Atom a;
-      int shift;
-      Bool on;
+  // figure out bit masks for the indicators we are interested in
+  for (int i = 0; i < XDESKTOP_N_LEDS; i++) {
+    Atom a;
+    int shift;
+    Bool on;
 
-      a = XInternAtom(dpy, ledNames[i], True);
-      if (!a || !XkbGetNamedIndicator(dpy, a, &shift, &on, NULL, NULL))
-        continue;
+    a = XInternAtom(dpy, ledNames[i], True);
+    if (!a || !XkbGetNamedIndicator(dpy, a, &shift, &on, NULL, NULL))
+      continue;
 
-      ledMasks[i] = 1u << shift;
-      vlog.debug("Mask for '%s' is 0x%x", ledNames[i], ledMasks[i]);
-      if (on)
-        ledState |= 1u << i;
-    }
+    ledMasks[i] = 1u << shift;
+    vlog.debug("Mask for '%s' is 0x%x", ledNames[i], ledMasks[i]);
+    if (on)
+      ledState |= 1u << i;
+  }
 
-    // X11 unfortunately uses keyboard driver specific keycodes and provides no
-    // direct way to query this, so guess based on the keyboard mapping
-    XkbDescPtr desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
-    if (desc && desc->names) {
-      char *keycodes = XGetAtomName(dpy, desc->names->keycodes);
+  // X11 unfortunately uses keyboard driver specific keycodes and provides no
+  // direct way to query this, so guess based on the keyboard mapping
+  XkbDescPtr desc = XkbGetKeyboard(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
+  if (desc && desc->names) {
+    char *keycodes = XGetAtomName(dpy, desc->names->keycodes);
 
-      if (keycodes) {
-        if (strncmp("evdev", keycodes, strlen("evdev")) == 0) {
-          codeMap = code_map_qnum_to_xorgevdev;
-          codeMapLen = code_map_qnum_to_xorgevdev_len;
-          vlog.info("Using evdev codemap\n");
-        } else if (strncmp("xfree86", keycodes, strlen("xfree86")) == 0) {
-          codeMap = code_map_qnum_to_xorgkbd;
-          codeMapLen = code_map_qnum_to_xorgkbd_len;
-          vlog.info("Using xorgkbd codemap\n");
-        } else {
-          vlog.info("Unknown keycode '%s', no codemap\n", keycodes);
-        }
-        XFree(keycodes);
+    if (keycodes) {
+      if (strncmp("evdev", keycodes, strlen("evdev")) == 0) {
+        codeMap = code_map_qnum_to_xorgevdev;
+        codeMapLen = code_map_qnum_to_xorgevdev_len;
+        vlog.info("Using evdev codemap\n");
+      } else if (strncmp("xfree86", keycodes, strlen("xfree86")) == 0) {
+        codeMap = code_map_qnum_to_xorgkbd;
+        codeMapLen = code_map_qnum_to_xorgkbd_len;
+        vlog.info("Using xorgkbd codemap\n");
       } else {
-        vlog.debug("Unable to get keycode map\n");
+        vlog.info("Unknown keycode '%s', no codemap\n", keycodes);
       }
-
-      XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
-    }
-
-#ifdef HAVE_XTEST
-    int xtestEventBase;
-    int xtestErrorBase;
-
-    if (XTestQueryExtension(dpy, &xtestEventBase,
-                            &xtestErrorBase, &major, &minor)) {
-      XTestGrabControl(dpy, True);
-      vlog.info("XTest extension present - version %d.%d",major,minor);
-      haveXtest = true;
+      XFree(keycodes);
     } else {
-#endif
-      vlog.info("XTest extension not present");
-      vlog.info("Unable to inject events or display while server is grabbed");
-#ifdef HAVE_XTEST
+      vlog.debug("Unable to get keycode map\n");
     }
+
+    XkbFreeKeyboard(desc, XkbAllComponentsMask, True);
+  }
+
+#ifdef HAVE_XTEST
+  int xtestEventBase;
+  int xtestErrorBase;
+
+  if (XTestQueryExtension(dpy, &xtestEventBase,
+                          &xtestErrorBase, &major, &minor)) {
+    XTestGrabControl(dpy, True);
+    vlog.info("XTest extension present - version %d.%d",major,minor);
+    haveXtest = true;
+  } else {
+#endif
+    vlog.info("XTest extension not present");
+    vlog.info("Unable to inject events or display while server is grabbed");
+#ifdef HAVE_XTEST
+  }
 #endif
 
 #ifdef HAVE_XDAMAGE
-    int xdamageErrorBase;
+  int xdamageErrorBase;
 
-    if (XDamageQueryExtension(dpy, &xdamageEventBase, &xdamageErrorBase)) {
-      haveDamage = true;
-    } else {
+  if (XDamageQueryExtension(dpy, &xdamageEventBase, &xdamageErrorBase)) {
+    haveDamage = true;
+  } else {
 #endif
-      vlog.info("DAMAGE extension not present");
-      vlog.info("Will have to poll screen for changes");
+    vlog.info("DAMAGE extension not present");
+    vlog.info("Will have to poll screen for changes");
 #ifdef HAVE_XDAMAGE
-    }
+  }
 #endif
 
 #ifdef HAVE_XFIXES
-    int xfixesErrorBase;
+  int xfixesErrorBase;
 
-    if (XFixesQueryExtension(dpy, &xfixesEventBase, &xfixesErrorBase)) {
-      XFixesSelectCursorInput(dpy, DefaultRootWindow(dpy),
-                              XFixesDisplayCursorNotifyMask);
-    } else {
+  if (XFixesQueryExtension(dpy, &xfixesEventBase, &xfixesErrorBase)) {
+    XFixesSelectCursorInput(dpy, DefaultRootWindow(dpy),
+                            XFixesDisplayCursorNotifyMask);
+  } else {
 #endif
-      vlog.info("XFIXES extension not present");
-      vlog.info("Will not be able to display cursors");
+    vlog.info("XFIXES extension not present");
+    vlog.info("Will not be able to display cursors");
 #ifdef HAVE_XFIXES
-    }
+  }
 #endif
 
-    TXWindow::setGlobalEventHandler(this);
+  TXWindow::setGlobalEventHandler(this);
 }
 
 XDesktop::~XDesktop() {
-    if (running)
-      stop();
+  if (running)
+    stop();
 }
 
 
 void XDesktop::poll() {
-    if (pb and not haveDamage)
-      pb->poll(server);
-    if (running) {
-      Window root, child;
-      int x, y, wx, wy;
-      unsigned int mask;
-      XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
-                    &x, &y, &wx, &wy, &mask);
-      server->setCursorPos(rfb::Point(x, y));
-    }
+  if (pb and not haveDamage)
+    pb->poll(server);
+  if (running) {
+    Window root, child;
+    int x, y, wx, wy;
+    unsigned int mask;
+    XQueryPointer(dpy, DefaultRootWindow(dpy), &root, &child,
+                  &x, &y, &wx, &wy, &mask);
+    server->setCursorPos(rfb::Point(x, y));
   }
+}
 
 
 void XDesktop::start(VNCServer* vs) {
 
-    // Determine actual number of buttons of the X pointer device.
-    unsigned char btnMap[8];
-    int numButtons = XGetPointerMapping(dpy, btnMap, 8);
-    maxButtons = (numButtons > 8) ? 8 : numButtons;
-    vlog.info("Enabling %d button%s of X pointer device",
-              maxButtons, (maxButtons != 1) ? "s" : "");
+  // Determine actual number of buttons of the X pointer device.
+  unsigned char btnMap[8];
+  int numButtons = XGetPointerMapping(dpy, btnMap, 8);
+  maxButtons = (numButtons > 8) ? 8 : numButtons;
+  vlog.info("Enabling %d button%s of X pointer device",
+            maxButtons, (maxButtons != 1) ? "s" : "");
 
-    // Create an ImageFactory instance for producing Image objects.
-    ImageFactory factory((bool)useShm);
+  // Create an ImageFactory instance for producing Image objects.
+  ImageFactory factory((bool)useShm);
 
-    // Create pixel buffer and provide it to the server object.
-    pb = new XPixelBuffer(dpy, factory, geometry->getRect());
-    vlog.info("Allocated %s", pb->getImage()->classDesc());
+  // Create pixel buffer and provide it to the server object.
+  pb = new XPixelBuffer(dpy, factory, geometry->getRect());
+  vlog.info("Allocated %s", pb->getImage()->classDesc());
 
-    server = (VNCServerST *)vs;
-    server->setPixelBuffer(pb);
+  server = (VNCServerST *)vs;
+  server->setPixelBuffer(pb);
 
 #ifdef HAVE_XDAMAGE
-    if (haveDamage) {
-      damage = XDamageCreate(dpy, DefaultRootWindow(dpy),
-                             XDamageReportRawRectangles);
-    }
+  if (haveDamage) {
+    damage = XDamageCreate(dpy, DefaultRootWindow(dpy),
+                           XDamageReportRawRectangles);
+  }
 #endif
 
 #ifdef HAVE_XFIXES
-    setCursor();
+  setCursor();
 #endif
 
-    server->setLEDState(ledState);
+  server->setLEDState(ledState);
 
-    running = true;
+  running = true;
 }
 
 void XDesktop::stop() {
-    running = false;
+  running = false;
 
 #ifdef HAVE_XDAMAGE
-    if (haveDamage)
-      XDamageDestroy(dpy, damage);
+  if (haveDamage)
+    XDamageDestroy(dpy, damage);
 #endif
 
-    server->setPixelBuffer(0);
-    server = 0;
+  server->setPixelBuffer(0);
+  server = 0;
 
-    delete pb;
-    pb = 0;
+  delete pb;
+  pb = 0;
 }
 
 bool XDesktop::isRunning() {
-    return running;
+  return running;
 }
 
 void XDesktop::pointerEvent(const Point& pos, int buttonMask) {
 #ifdef HAVE_XTEST
-    if (!haveXtest) return;
-    XTestFakeMotionEvent(dpy, DefaultScreen(dpy),
-                         geometry->offsetLeft() + pos.x,
-                         geometry->offsetTop() + pos.y,
-                         CurrentTime);
-    if (buttonMask != oldButtonMask) {
-      for (int i = 0; i < maxButtons; i++) {
-	if ((buttonMask ^ oldButtonMask) & (1<<i)) {
-          if (buttonMask & (1<<i)) {
-            XTestFakeButtonEvent(dpy, i+1, True, CurrentTime);
-          } else {
-            XTestFakeButtonEvent(dpy, i+1, False, CurrentTime);
-          }
+  if (!haveXtest) return;
+  XTestFakeMotionEvent(dpy, DefaultScreen(dpy),
+                       geometry->offsetLeft() + pos.x,
+                       geometry->offsetTop() + pos.y,
+                       CurrentTime);
+  if (buttonMask != oldButtonMask) {
+    for (int i = 0; i < maxButtons; i++) {
+      if ((buttonMask ^ oldButtonMask) & (1<<i)) {
+        if (buttonMask & (1<<i)) {
+          XTestFakeButtonEvent(dpy, i+1, True, CurrentTime);
+        } else {
+          XTestFakeButtonEvent(dpy, i+1, False, CurrentTime);
         }
       }
     }
-    oldButtonMask = buttonMask;
+  }
+  oldButtonMask = buttonMask;
 #endif
 }
 
 #ifdef HAVE_XTEST
 KeyCode XDesktop::XkbKeysymToKeycode(Display* dpy, KeySym keysym) {
-    XkbDescPtr xkb;
-    XkbStateRec state;
-    unsigned keycode;
+  XkbDescPtr xkb;
+  XkbStateRec state;
+  unsigned keycode;
 
-    xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
-    if (!xkb)
-      return 0;
+  xkb = XkbGetMap(dpy, XkbAllComponentsMask, XkbUseCoreKbd);
+  if (!xkb)
+    return 0;
 
-    XkbGetState(dpy, XkbUseCoreKbd, &state);
+  XkbGetState(dpy, XkbUseCoreKbd, &state);
 
-    for (keycode = xkb->min_key_code;
-         keycode <= xkb->max_key_code;
-         keycode++) {
-      KeySym cursym;
-      unsigned int mods, out_mods;
-      // XkbStateFieldFromRec() doesn't work properly because
-      // state.lookup_mods isn't properly updated, so we do this manually
-      mods = XkbBuildCoreState(XkbStateMods(&state), state.group);
-      XkbTranslateKeyCode(xkb, keycode, mods, &out_mods, &cursym);
-      if (cursym == keysym)
-        break;
-    }
+  for (keycode = xkb->min_key_code;
+       keycode <= xkb->max_key_code;
+       keycode++) {
+    KeySym cursym;
+    unsigned int mods, out_mods;
+    // XkbStateFieldFromRec() doesn't work properly because
+    // state.lookup_mods isn't properly updated, so we do this manually
+    mods = XkbBuildCoreState(XkbStateMods(&state), state.group);
+    XkbTranslateKeyCode(xkb, keycode, mods, &out_mods, &cursym);
+    if (cursym == keysym)
+      break;
+  }
 
-    if (keycode > xkb->max_key_code)
-      keycode = 0;
+  if (keycode > xkb->max_key_code)
+    keycode = 0;
 
-    XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
+  XkbFreeKeyboard(xkb, XkbAllComponentsMask, True);
 
-    return keycode;
+  return keycode;
 }
 #endif
 
 void XDesktop::keyEvent(rdr::U32 keysym, rdr::U32 xtcode, bool down) {
 #ifdef HAVE_XTEST
-    int keycode = 0;
+  int keycode = 0;
 
-    if (!haveXtest)
-      return;
+  if (!haveXtest)
+    return;
 
-    // Use scan code if provided and mapping exists
-    if (codeMap && rawKeyboard && xtcode < codeMapLen)
-        keycode = codeMap[xtcode];
+  // Use scan code if provided and mapping exists
+  if (codeMap && rawKeyboard && xtcode < codeMapLen)
+      keycode = codeMap[xtcode];
 
-    if (!keycode) {
-      if (pressedKeys.find(keysym) != pressedKeys.end())
-        keycode = pressedKeys[keysym];
-      else {
-        // XKeysymToKeycode() doesn't respect state, so we have to use
-        // something slightly more complex
-        keycode = XkbKeysymToKeycode(dpy, keysym);
-      }
+  if (!keycode) {
+    if (pressedKeys.find(keysym) != pressedKeys.end())
+      keycode = pressedKeys[keysym];
+    else {
+      // XKeysymToKeycode() doesn't respect state, so we have to use
+      // something slightly more complex
+      keycode = XkbKeysymToKeycode(dpy, keysym);
     }
+  }
 
-    if (!keycode)
-      return;
+  if (!keycode)
+    return;
 
-    if (down)
-      pressedKeys[keysym] = keycode;
-    else
-      pressedKeys.erase(keysym);
+  if (down)
+    pressedKeys[keysym] = keycode;
+  else
+    pressedKeys.erase(keysym);
 
-    XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
+  XTestFakeKeyEvent(dpy, keycode, down, CurrentTime);
 #endif
 }
 
@@ -333,102 +333,102 @@
 
 
 bool XDesktop::handleGlobalEvent(XEvent* ev) {
-    if (ev->type == xkbEventBase + XkbEventCode) {
-      XkbEvent *kb = (XkbEvent *)ev;
+  if (ev->type == xkbEventBase + XkbEventCode) {
+    XkbEvent *kb = (XkbEvent *)ev;
 
-      if (kb->any.xkb_type != XkbIndicatorStateNotify)
-        return false;
+    if (kb->any.xkb_type != XkbIndicatorStateNotify)
+      return false;
 
-      vlog.debug("Got indicator update, mask is now 0x%x", kb->indicators.state);
+    vlog.debug("Got indicator update, mask is now 0x%x", kb->indicators.state);
 
-      ledState = 0;
-      for (int i = 0; i < XDESKTOP_N_LEDS; i++) {
-        if (kb->indicators.state & ledMasks[i])
-          ledState |= 1u << i;
-      }
-
-      if (running)
-        server->setLEDState(ledState);
-
-      return true;
-#ifdef HAVE_XDAMAGE
-    } else if (ev->type == xdamageEventBase) {
-      XDamageNotifyEvent* dev;
-      Rect rect;
-
-      if (!running)
-        return true;
-
-      dev = (XDamageNotifyEvent*)ev;
-      rect.setXYWH(dev->area.x, dev->area.y, dev->area.width, dev->area.height);
-      server->add_changed(rect);
-
-      return true;
-#endif
-#ifdef HAVE_XFIXES
-    } else if (ev->type == xfixesEventBase + XFixesCursorNotify) {
-      XFixesCursorNotifyEvent* cev;
-
-      if (!running)
-        return true;
-
-      cev = (XFixesCursorNotifyEvent*)ev;
-
-      if (cev->subtype != XFixesDisplayCursorNotify)
-        return false;
-
-      return setCursor();
-#endif
+    ledState = 0;
+    for (int i = 0; i < XDESKTOP_N_LEDS; i++) {
+      if (kb->indicators.state & ledMasks[i])
+        ledState |= 1u << i;
     }
 
-    return false;
+    if (running)
+      server->setLEDState(ledState);
+
+    return true;
+#ifdef HAVE_XDAMAGE
+  } else if (ev->type == xdamageEventBase) {
+    XDamageNotifyEvent* dev;
+    Rect rect;
+
+    if (!running)
+      return true;
+
+    dev = (XDamageNotifyEvent*)ev;
+    rect.setXYWH(dev->area.x, dev->area.y, dev->area.width, dev->area.height);
+    server->add_changed(rect);
+
+    return true;
+#endif
+#ifdef HAVE_XFIXES
+  } else if (ev->type == xfixesEventBase + XFixesCursorNotify) {
+    XFixesCursorNotifyEvent* cev;
+
+    if (!running)
+      return true;
+
+    cev = (XFixesCursorNotifyEvent*)ev;
+
+    if (cev->subtype != XFixesDisplayCursorNotify)
+      return false;
+
+    return setCursor();
+#endif
+  }
+
+  return false;
 }
 
 bool XDesktop::setCursor()
 {
-      XFixesCursorImage *cim;
+  XFixesCursorImage *cim;
 
-      cim = XFixesGetCursorImage(dpy);
-      if (cim == NULL)
-        return false;
+  cim = XFixesGetCursorImage(dpy);
+  if (cim == NULL)
+    return false;
 
-      // Copied from XserverDesktop::setCursor() in
-      // unix/xserver/hw/vnc/XserverDesktop.cc and adapted to
-      // handle long -> U32 conversion for 64-bit Xlib
-      rdr::U8* cursorData;
-      rdr::U8 *out;
-      const unsigned long *pixels;
+  // Copied from XserverDesktop::setCursor() in
+  // unix/xserver/hw/vnc/XserverDesktop.cc and adapted to
+  // handle long -> U32 conversion for 64-bit Xlib
+  rdr::U8* cursorData;
+  rdr::U8 *out;
+  const unsigned long *pixels;
 
-      cursorData = new rdr::U8[cim->width * cim->height * 4];
+  cursorData = new rdr::U8[cim->width * cim->height * 4];
 
-      // Un-premultiply alpha
-      pixels = cim->pixels;
-      out = cursorData;
-      for (int y = 0; y < cim->height; y++) {
-        for (int x = 0; x < cim->width; x++) {
-          rdr::U8 alpha;
-          rdr::U32 pixel = *pixels++;
-          rdr::U8 *in = (rdr::U8 *) &pixel;
+  // Un-premultiply alpha
+  pixels = cim->pixels;
+  out = cursorData;
+  for (int y = 0; y < cim->height; y++) {
+    for (int x = 0; x < cim->width; x++) {
+      rdr::U8 alpha;
+      rdr::U32 pixel = *pixels++;
+      rdr::U8 *in = (rdr::U8 *) &pixel;
 
-          alpha = in[3];
-          if (alpha == 0)
-            alpha = 1; // Avoid division by zero
+      alpha = in[3];
+      if (alpha == 0)
+        alpha = 1; // Avoid division by zero
 
-          *out++ = (unsigned)*in++ * 255/alpha;
-          *out++ = (unsigned)*in++ * 255/alpha;
-          *out++ = (unsigned)*in++ * 255/alpha;
-          *out++ = *in++;
-        }
-      }
+      *out++ = (unsigned)*in++ * 255/alpha;
+      *out++ = (unsigned)*in++ * 255/alpha;
+      *out++ = (unsigned)*in++ * 255/alpha;
+      *out++ = *in++;
+    }
+  }
 
-      try {
-        server->setCursor(cim->width, cim->height, Point(cim->xhot, cim->yhot),
-                          cursorData);
-      } catch (rdr::Exception& e) {
-        vlog.error("XserverDesktop::setCursor: %s",e.str());
-      }
+  try {
+    server->setCursor(cim->width, cim->height, Point(cim->xhot, cim->yhot),
+                      cursorData);
+  } catch (rdr::Exception& e) {
+    vlog.error("XserverDesktop::setCursor: %s",e.str());
+  }
 
-      delete [] cursorData;
-      XFree(cim);
-      return true;
+  delete [] cursorData;
+  XFree(cim);
+  return true;
 }
