diff --git a/README.md b/README.md
index 39737f25..22891cfc 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 [![Build Status](https://travis-ci.org/neutrinolabs/xorgxrdp.svg?branch=devel)](https://travis-ci.org/neutrinolabs/xorgxrdp)
 
-*Current Version:* 0.2.9
+*Current Version:* 0.2.10
 
 # xorgxrdp
 
diff --git a/configure b/configure
index d4073499..ebab171c 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for xorgxrdp 0.2.9.
+# Generated by GNU Autoconf 2.69 for xorgxrdp 0.2.10.
 #
 # Report bugs to <xrdp-devel@googlegroups.com>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='xorgxrdp'
 PACKAGE_TARNAME='xorgxrdp'
-PACKAGE_VERSION='0.2.9'
-PACKAGE_STRING='xorgxrdp 0.2.9'
+PACKAGE_VERSION='0.2.10'
+PACKAGE_STRING='xorgxrdp 0.2.10'
 PACKAGE_BUGREPORT='xrdp-devel@googlegroups.com'
 PACKAGE_URL=''
 
@@ -1338,7 +1338,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xorgxrdp 0.2.9 to adapt to many kinds of systems.
+\`configure' configures xorgxrdp 0.2.10 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1408,7 +1408,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xorgxrdp 0.2.9:";;
+     short | recursive ) echo "Configuration of xorgxrdp 0.2.10:";;
    esac
   cat <<\_ACEOF
 
@@ -1532,7 +1532,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-xorgxrdp configure 0.2.9
+xorgxrdp configure 0.2.10
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1810,7 +1810,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xorgxrdp $as_me 0.2.9, which was
+It was created by xorgxrdp $as_me 0.2.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2684,7 +2684,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='xorgxrdp'
- VERSION='0.2.9'
+ VERSION='0.2.10'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13533,7 +13533,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by xorgxrdp $as_me 0.2.9, which was
+This file was extended by xorgxrdp $as_me 0.2.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13599,7 +13599,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-xorgxrdp config.status 0.2.9
+xorgxrdp config.status 0.2.10
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index c94f9e15..f3504c08 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 
 AC_PREREQ(2.65)
 # package version must be x.y.z
-AC_INIT([xorgxrdp], [0.2.9], [xrdp-devel@googlegroups.com])
+AC_INIT([xorgxrdp], [0.2.10], [xrdp-devel@googlegroups.com])
 package_version_major=$(echo ${PACKAGE_VERSION}|cut -d. -f1)
 package_version_minor=$(echo ${PACKAGE_VERSION}|cut -d. -f2)
 package_version_patchlevel=$(echo ${PACKAGE_VERSION}|cut -d. -f3)
diff --git a/debian/changelog b/debian/changelog
index ff58db37..5cbc5038 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+xorgxrdp (1:0.2.10-1) UNRELEASED; urgency=medium
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Tue, 30 Jul 2019 02:45:10 +0000
+
 xorgxrdp (1:0.2.9-1) unstable; urgency=medium
 
   * New upstream version.
diff --git a/debian/patches/fix_perms.diff b/debian/patches/fix_perms.diff
index 4a3bb304..91fd6682 100644
--- a/debian/patches/fix_perms.diff
+++ b/debian/patches/fix_perms.diff
@@ -6,9 +6,11 @@ Subject: Fix permissions between xrdp and sesman.
  can’t easily chgrp here; also fix retval check for listen(2)
 Forwarded: https://github.com/neutrinolabs/xorgxrdp/pull/16
  https://github.com/neutrinolabs/xrdp/pull/464
---- a/module/rdpClientCon.c
-+++ b/module/rdpClientCon.c
-@@ -1231,7 +1231,7 @@ rdpClientConInit(rdpPtr dev)
+Index: xorgxrdp/module/rdpClientCon.c
+===================================================================
+--- xorgxrdp.orig/module/rdpClientCon.c
++++ xorgxrdp/module/rdpClientCon.c
+@@ -1330,7 +1330,7 @@ rdpClientConInit(rdpPtr dev)
                  return 0;
              }
          }
diff --git a/debian/patches/lfs.diff b/debian/patches/lfs.diff
index b9aaa15d..da01abe9 100644
--- a/debian/patches/lfs.diff
+++ b/debian/patches/lfs.diff
@@ -2,8 +2,10 @@ From: Thorsten Glaser <tg@mirbsd.org>
 Subject: Enable Large File Support on (at least) 32-bit Linux
 Forwarded: https://github.com/neutrinolabs/xrdp/issues/647
 Reviewed-by: Dominik George <nik@naturalnet.de>
---- a/configure.ac
-+++ b/configure.ac
+Index: xorgxrdp/configure.ac
+===================================================================
+--- xorgxrdp.orig/configure.ac
++++ xorgxrdp/configure.ac
 @@ -13,6 +13,8 @@ AC_CONFIG_HEADERS(config_ac.h:config_ac-
  AM_INIT_AUTOMAKE([1.11 foreign parallel-tests])
  m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
diff --git a/debian/patches/misc-fixes.diff b/debian/patches/misc-fixes.diff
index 2a3bba50..ba06c4c6 100644
--- a/debian/patches/misc-fixes.diff
+++ b/debian/patches/misc-fixes.diff
@@ -2,9 +2,11 @@ From: Thorsten Glaser <tg@mirbsd.org>
 Subject: misc. fixes
 Forwarded: https://github.com/neutrinolabs/xorgxrdp/pull/17
  https://github.com/neutrinolabs/xrdp/pull/467
---- a/xrdpkeyb/rdpKeyboard.c
-+++ b/xrdpkeyb/rdpKeyboard.c
-@@ -538,7 +538,7 @@ rdpInputKeyboard(rdpPtr dev, int msg, lo
+Index: xorgxrdp/xrdpkeyb/rdpKeyboard.c
+===================================================================
+--- xorgxrdp.orig/xrdpkeyb/rdpKeyboard.c
++++ xorgxrdp/xrdpkeyb/rdpKeyboard.c
+@@ -536,7 +536,7 @@ rdpInputKeyboard(rdpPtr dev, int msg, lo
  }
  
  /******************************************************************************/
@@ -13,7 +15,7 @@ Forwarded: https://github.com/neutrinolabs/xorgxrdp/pull/17
  rdpkeybDeviceInit(DeviceIntPtr pDevice, KeySymsPtr pKeySyms, CARD8 *pModMap)
  {
      int i;
-@@ -569,7 +569,7 @@ rdpkeybDeviceInit(DeviceIntPtr pDevice,
+@@ -567,7 +567,7 @@ rdpkeybDeviceInit(DeviceIntPtr pDevice,
      if (pKeySyms->map == 0)
      {
          LLOGLN(0, ("rdpkeybDeviceInit: out of memory"));
@@ -22,7 +24,7 @@ Forwarded: https://github.com/neutrinolabs/xorgxrdp/pull/17
      }
  
      for (i = 0; i < MAP_LENGTH * GLYPHS_PER_KEY; i++)
-@@ -581,6 +581,8 @@ rdpkeybDeviceInit(DeviceIntPtr pDevice,
+@@ -579,6 +579,8 @@ rdpkeybDeviceInit(DeviceIntPtr pDevice,
      {
          pKeySyms->map[i] = g_kbdMap[i];
      }
@@ -31,7 +33,7 @@ Forwarded: https://github.com/neutrinolabs/xorgxrdp/pull/17
  }
  
  /******************************************************************************/
-@@ -676,7 +678,8 @@ rdpkeybControl(DeviceIntPtr device, int
+@@ -687,7 +689,8 @@ rdpkeybControl(DeviceIntPtr device, int
      switch (what)
      {
          case DEVICE_INIT:
diff --git a/module/rdp.h b/module/rdp.h
index a6805266..85dba260 100644
--- a/module/rdp.h
+++ b/module/rdp.h
@@ -282,11 +282,11 @@ struct _rdpRec
 
     OsTimerPtr disconnectTimer;
     int disconnect_timeout_s;
-    int disconnect_time_ms;
+    CARD32 disconnect_time_ms;
 
     OsTimerPtr idleDisconnectTimer;
     int idle_disconnect_timeout_s;
-    time_t last_event_time;
+    CARD32 last_event_time_ms;
 
     int conNumber;
 
diff --git a/module/rdpClientCon.c b/module/rdpClientCon.c
index a098a99b..c026a6a3 100644
--- a/module/rdpClientCon.c
+++ b/module/rdpClientCon.c
@@ -210,7 +210,7 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
     LLOGLN(0, ("rdpClientConGotConnection:"));
     clientCon = g_new0(rdpClientCon, 1);
     clientCon->dev = dev;
-    dev->last_event_time = time(0);
+    dev->last_event_time_ms = GetTimeInMillis();
     dev->do_dirty_ons = 1;
 
     make_stream(clientCon->in_s);
@@ -253,7 +253,7 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
     {
         LLOGLN(0, ("rdpClientConGetConnection: "
                    "engaging idle timer, timeout [%d] sec", dev->idle_disconnect_timeout_s));
-        dev->idleDisconnectTimer = TimerSet(dev->idleDisconnectTimer, 0, 1000 * 1,
+        dev->idleDisconnectTimer = TimerSet(dev->idleDisconnectTimer, 0, dev->idle_disconnect_timeout_s * 1000,
                                             rdpDeferredIdleDisconnectCallback, dev);
     }
     else
@@ -274,7 +274,6 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
 static CARD32
 rdpDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg)
 {
-    CARD32 lnow_ms;
     rdpPtr dev;
 
     dev = (rdpPtr) arg;
@@ -297,8 +296,7 @@ rdpDeferredDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg)
     {
         LLOGLN(10, ("rdpDeferredDisconnectCallback: not connected"));
     }
-    lnow_ms = GetTimeInMillis();
-    if (lnow_ms - dev->disconnect_time_ms > dev->disconnect_timeout_s * 1000)
+    if (now - dev->disconnect_time_ms > dev->disconnect_timeout_s * 1000)
     {
         LLOGLN(0, ("rdpDeferredDisconnectCallback: "
                    "disconnect timeout exceeded, exiting"));
@@ -317,26 +315,16 @@ rdpDeferredIdleDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg)
     LLOGLN(10, ("rdpDeferredIdleDisconnectCallback:"));
 
     rdpPtr dev;
-    time_t current_time;
 
     dev = (rdpPtr) arg;
-    current_time = time(0);
 
-    if (dev->idle_disconnect_timeout_s <= 0)
-    {
-        /* should not reach here */
-        LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: timeout set to non-positive value, disengaging timer"));
-        goto cancel_timer;
-    }
+    CARD32 millis_since_last_event;
 
-    if (dev->last_event_time > now)
-    {
-        LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: time has gone backwards, resetting"));
-        dev->last_event_time = current_time;
-        goto next_timer;
-    }
+    /* how many millis was the last event ago? */
+    millis_since_last_event = now - dev->last_event_time_ms;
 
-    if (current_time - dev->last_event_time > dev->idle_disconnect_timeout_s)
+    /* we MUST compare to equal otherwise we could restart the idle timer with 0! */
+    if (millis_since_last_event >= (dev->idle_disconnect_timeout_s * 1000))
     {
         LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: session has been idle for %d seconds, disconnecting",
                     dev->idle_disconnect_timeout_s));
@@ -348,20 +336,18 @@ rdpDeferredIdleDisconnectCallback(OsTimerPtr timer, CARD32 now, pointer arg)
         }
 
         LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: disconnected idle session"));
-        goto cancel_timer;
+
+        TimerCancel(dev->idleDisconnectTimer);
+        TimerFree(dev->idleDisconnectTimer);
+        dev->idleDisconnectTimer = NULL;
+        LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: idle timer disengaged"));
+        return 0;
     }
 
-next_timer:
-    dev->idleDisconnectTimer = TimerSet(dev->idleDisconnectTimer, 0, 1000 * 1,
+    /* restart the idle timer with last_event + idle timeout */
+    dev->idleDisconnectTimer = TimerSet(dev->idleDisconnectTimer, 0, (dev->idle_disconnect_timeout_s * 1000) - millis_since_last_event,
                                         rdpDeferredIdleDisconnectCallback, dev);
     return 0;
-
-cancel_timer:
-    TimerCancel(dev->idleDisconnectTimer);
-    TimerFree(dev->idleDisconnectTimer);
-    dev->idleDisconnectTimer = NULL;
-    LLOGLN(0, ("rdpDeferredIdleDisconnectCallback: idle timer disengaged"));
-    return 0;
 }
 /*****************************************************************************/
 static int
@@ -1075,6 +1061,35 @@ rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon)
     return 0;
 }
 
+/******************************************************************************/
+static int
+rdpClientConProcessMsgClientSuppressOutput(rdpPtr dev, rdpClientCon *clientCon)
+{
+    int suppress;
+    int left;
+    int top;
+    int right;
+    int bottom;
+    struct stream *s;
+
+    s = clientCon->in_s;
+    in_uint32_le(s, suppress);
+    in_uint32_le(s, left);
+    in_uint32_le(s, top);
+    in_uint32_le(s, right);
+    in_uint32_le(s, bottom);
+    LLOGLN(10, ("rdpClientConProcessMsgClientSuppressOutput: "
+           "suppress %d left %d top %d right %d bottom %d",
+           suppress, left, top, right, bottom));
+    clientCon->suppress_output = suppress;
+    if (suppress == 0)
+    {
+        rdpClientConAddDirtyScreen(dev, clientCon, left, top,
+                                   right - left, bottom - top);
+    }
+    return 0;
+}
+
 /******************************************************************************/
 static int
 rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
@@ -1100,7 +1115,12 @@ rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
         case 106: /* client region ex */
             rdpClientConProcessMsgClientRegionEx(dev, clientCon);
             break;
+        case 108: /* client suppress output */
+            rdpClientConProcessMsgClientSuppressOutput(dev, clientCon);
+            break;
         default:
+            LLOGLN(0, ("rdpClientConProcessMsg: unknown msg_type %d",
+                   msg_type));
             break;
     }
 
@@ -2397,7 +2417,12 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
 
     LLOGLN(10, ("rdpDeferredUpdateCallback:"));
     clientCon = (rdpClientCon *) arg;
-
+    clientCon->updateScheduled = FALSE;
+    if (clientCon->suppress_output)
+    {
+        LLOGLN(10, ("rdpDeferredUpdateCallback: suppress_output set"));
+        return 0;
+    }
     if ((clientCon->rect_id > clientCon->rect_id_ack) ||
         /* do not allow captures until we have the client_info */
         clientCon->client_info.size == 0)
@@ -2408,6 +2433,7 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
         clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
                                           rdpDeferredUpdateCallback,
                                           clientCon);
+        clientCon->updateScheduled = TRUE;
         return 0;
     }
     else
@@ -2419,7 +2445,6 @@ rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
            "rdp_Bpp %d screen width %d screen height %d",
            clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
            id.width, id.height));
-    clientCon->updateScheduled = FALSE;
     if (clientCon->dev->monitorCount < 1)
     {
         dirty_extents = *rdpRegionExtents(clientCon->dirtyRegion);
diff --git a/module/rdpClientCon.h b/module/rdpClientCon.h
index 0df6161b..52243022 100644
--- a/module/rdpClientCon.h
+++ b/module/rdpClientCon.h
@@ -112,6 +112,9 @@ struct _rdpClientCon
     int num_rfx_crcs_alloc;
     int *rfx_crcs;
 
+    /* true = skip drawing */
+    int suppress_output;
+
     struct _rdpClientCon *next;
     struct _rdpClientCon *prev;
 };
diff --git a/module/rdpCursor.c b/module/rdpCursor.c
index 2495622c..fceacfce 100644
--- a/module/rdpCursor.c
+++ b/module/rdpCursor.c
@@ -245,7 +245,11 @@ rdpSpriteSetCursorCon(rdpClientCon *clientCon,
     int bpp;
 
     LLOGLN(10, ("rdpSpriteSetCursorCon:"));
-
+    if (clientCon->suppress_output)
+    {
+        LLOGLN(10, ("rdpSpriteSetCursorCon: suppress_output set"));
+        return;
+    }
     w = pCurs->bits->width;
     h = pCurs->bits->height;
     if ((pCurs->bits->argb != 0) &&
diff --git a/module/rdpInput.c b/module/rdpInput.c
index 36f7e617..daedf39b 100644
--- a/module/rdpInput.c
+++ b/module/rdpInput.c
@@ -98,7 +98,7 @@ rdpInputKeyboardEvent(rdpPtr dev, int msg,
                       long param1, long param2,
                       long param3, long param4)
 {
-    dev->last_event_time = time(0);
+    dev->last_event_time_ms = GetTimeInMillis();
 
     if (g_input_proc[0].proc != 0)
     {
@@ -113,7 +113,7 @@ rdpInputMouseEvent(rdpPtr dev, int msg,
                    long param1, long param2,
                    long param3, long param4)
 {
-    dev->last_event_time = time(0);
+    dev->last_event_time_ms = GetTimeInMillis();
 
     if (g_input_proc[1].proc != 0)
     {