GUACAMOLE-1686: Merge improved WOL functionality.

diff --git a/configure.ac b/configure.ac
index d05346c..c0394ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,9 @@
 AC_PROG_CC_C99
 AC_PROG_LIBTOOL
 
+# Initialize pkg-config support
+PKG_PROG_PKG_CONFIG()
+
 # Headers
 AC_CHECK_HEADERS([fcntl.h stdlib.h string.h sys/socket.h time.h sys/time.h syslog.h unistd.h cairo/cairo.h pngstruct.h])
 
@@ -145,34 +148,34 @@
 AC_CHECK_FUNCS([clock_gettime gettimeofday memmove memset select strdup nanosleep])
 
 AC_CHECK_DECL([png_get_io_ptr],
-	[AC_DEFINE([HAVE_PNG_GET_IO_PTR],,
+    [AC_DEFINE([HAVE_PNG_GET_IO_PTR],,
                [Whether png_get_io_ptr() is defined])],,
-	[#include <png.h>])
+    [#include <png.h>])
 
 AC_CHECK_DECL([cairo_format_stride_for_width],
-	[AC_DEFINE([HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH],,
+    [AC_DEFINE([HAVE_CAIRO_FORMAT_STRIDE_FOR_WIDTH],,
                [Whether cairo_format_stride_for_width() is defined])],,
-	[#include <cairo/cairo.h>])
+    [#include <cairo/cairo.h>])
 
 AC_CHECK_DECL([poll],
-	[AC_DEFINE([HAVE_POLL],,
+    [AC_DEFINE([HAVE_POLL],,
                [Whether poll() is defined])],,
-	[#include <poll.h>])
+    [#include <poll.h>])
 
 AC_CHECK_DECL([strlcpy],
-	[AC_DEFINE([HAVE_STRLCPY],,
+    [AC_DEFINE([HAVE_STRLCPY],,
                [Whether strlcpy() is defined])],,
-	[#include <string.h>])
+    [#include <string.h>])
 
 AC_CHECK_DECL([strlcat],
-	[AC_DEFINE([HAVE_STRLCAT],,
+    [AC_DEFINE([HAVE_STRLCAT],,
                [Whether strlcat() is defined])],,
-	[#include <string.h>])
+    [#include <string.h>])
 
 AC_CHECK_DECL([strnstr],
-	[AC_DEFINE([HAVE_STRNSTR],,
+    [AC_DEFINE([HAVE_STRNSTR],,
                [Whether strnstr() is defined])],,
-	[#include <string.h>])
+    [#include <string.h>])
 
 # Typedefs
 AC_TYPE_SIZE_T
@@ -255,10 +258,11 @@
 
 have_libavformat=disabled
 AC_ARG_WITH([libavformat],
-	    [AS_HELP_STRING([--with-libavformat],
-	                    [use libavformat when encoding video @<:@default=check@:>@])],
-            [].
+            [AS_HELP_STRING([--with-libavformat],
+                            [use libavformat when encoding video @<:@default=check@:>@])],
+            [],
             [with_libavformat=check])
+
 if test "x$with_libavformat" != "xno"
 then
     have_libavformat=yes
@@ -984,9 +988,8 @@
 
 fi
 
-AM_CONDITIONAL([ENABLE_SSH_AGENT],
-	   [test "x${have_ssh_agent}"   = "xyes" \
-	      -a "x${enable_ssh_agent}" = "xyes"])
+AM_CONDITIONAL([ENABLE_SSH_AGENT], [test "x${have_ssh_agent}"   = "xyes" \
+                                      -a "x${enable_ssh_agent}" = "xyes"])
 
 #
 # libtelnet
diff --git a/src/libguac/rwlock.c b/src/libguac/rwlock.c
index 22d041b..1ed7176 100644
--- a/src/libguac/rwlock.c
+++ b/src/libguac/rwlock.c
@@ -179,7 +179,7 @@
      * write lock by another function without the caller knowing about it. This
      * shouldn't cause any issues, however.
      */
-    if (key_value == GUAC_REENTRANT_LOCK_READ_LOCK)
+    if (flag == GUAC_REENTRANT_LOCK_READ_LOCK)
         pthread_rwlock_unlock(&(reentrant_rwlock->lock));
 
     /* Acquire the write lock */
diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c
index 083a6c6..09ee8a7 100644
--- a/src/protocols/vnc/settings.c
+++ b/src/protocols/vnc/settings.c
@@ -87,6 +87,7 @@
     "recording-write-existing",
     "disable-copy",
     "disable-paste",
+    "disable-server-input",
     
     "wol-send-packet",
     "wol-mac-addr",
@@ -95,6 +96,8 @@
     "wol-wait-time",
 
     "force-lossless",
+    "compress-level",
+    "quality-level",
     NULL
 };
 
@@ -351,6 +354,12 @@
      * using the clipboard. By default, clipboard access is not blocked.
      */
     IDX_DISABLE_PASTE,
+
+    /**
+     * Whether or not to disable the input on the server side when the VNC client
+     * is connected. The default is not to disable the input.
+     */
+    IDX_DISABLE_SERVER_INPUT,
     
     /**
      * Whether to send the magic Wake-on-LAN (WoL) packet to wake the remote
@@ -389,6 +398,18 @@
      */
     IDX_FORCE_LOSSLESS,
 
+    /**
+     * The level of compression, on a scale of 0 (no compression) to 9 (maximum
+     * compression), that the connection will be configured for.
+     */
+    IDX_COMPRESS_LEVEL,
+
+    /**
+     * The level of display quality, on a scale of 0 (worst quality) to 9 (best
+     * quality), that the connection will be configured for.
+     */
+    IDX_QUALITY_LEVEL,
+
     VNC_ARGS_COUNT
 };
 
@@ -443,6 +464,11 @@
         guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
                 IDX_READ_ONLY, false);
 
+    /* Disable server input */
+    settings->disable_server_input =
+            guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
+                                         IDX_DISABLE_SERVER_INPUT, false);
+
     /* Parse color depth */
     settings->color_depth =
         guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv,
@@ -453,6 +479,16 @@
         guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
                 IDX_FORCE_LOSSLESS, false);
 
+    /* Compression level */
+    settings->compress_level =
+        guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv,
+                IDX_COMPRESS_LEVEL, -1);
+
+    /* Display quality */
+    settings->quality_level =
+        guac_user_parse_args_int(user, GUAC_VNC_CLIENT_ARGS, argv,
+                IDX_QUALITY_LEVEL, -1);
+
 #ifdef ENABLE_VNC_REPEATER
     /* Set repeater parameters if specified */
     settings->dest_host =
diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h
index 3803434..3b88581 100644
--- a/src/protocols/vnc/settings.h
+++ b/src/protocols/vnc/settings.h
@@ -82,6 +82,16 @@
      */
     bool lossless;
 
+    /**
+     * The level of compression to ask the VNC client library to perform.
+     */
+    int compress_level;
+
+     /**
+      * The quality level to ask the VNC client library to maintain.
+      */
+    int quality_level;
+
 #ifdef ENABLE_VNC_REPEATER
     /**
      * The VNC host to connect to, if using a repeater.
@@ -311,6 +321,11 @@
      */
     int wol_wait_time;
 
+    /**
+     * Whether or not to disable the input on the server side.
+     */
+    bool disable_server_input;
+
 } guac_vnc_settings;
 
 /**
diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c
index e3c6602..ec2c505 100644
--- a/src/protocols/vnc/vnc.c
+++ b/src/protocols/vnc/vnc.c
@@ -449,6 +449,20 @@
     }
 #endif
 
+    /* Disable remote console (Server input) */
+    if (settings->disable_server_input) {
+        rfbSetServerInputMsg msg;
+        msg.type = rfbSetServerInput;
+        msg.status = 1;
+        msg.pad = 0;
+
+        if (WriteToRFBServer(rfb_client, (char*)&msg, sz_rfbSetServerInputMsg))
+            guac_client_log(client, GUAC_LOG_DEBUG, "Successfully sent request to disable server input.");
+
+        else
+            guac_client_log(client, GUAC_LOG_WARNING, "Failed to send request to disable server input.");
+    }
+
     /* Set remaining client data */
     vnc_client->rfb_client = rfb_client;
 
@@ -473,6 +487,13 @@
      * heuristics) */
     guac_common_display_set_lossless(vnc_client->display, settings->lossless);
 
+    /* If compression and display quality have been configured, set those. */
+    if (settings->compress_level >= 0 && settings->compress_level <= 9)
+        rfb_client->appData.compressLevel = settings->compress_level;
+
+    if (settings->quality_level >= 0 && settings->quality_level <= 9)
+        rfb_client->appData.qualityLevel = settings->quality_level;
+
     /* If not read-only, set an appropriate cursor */
     if (settings->read_only == 0) {
         if (settings->remote_cursor)
diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c
index 25a5b13..68b3ad2 100644
--- a/src/terminal/terminal.c
+++ b/src/terminal/terminal.c
@@ -1751,6 +1751,10 @@
 static int __guac_terminal_send_mouse(guac_terminal* term, guac_user* user,
         int x, int y, int mask) {
 
+    /* Remove display margin from mouse position without going below 0 */
+    y = y >= term->display->margin ? y - term->display->margin : 0;
+    x = x >= term->display->margin ? x - term->display->margin : 0;
+
     /* Ignore user input if terminal is not started */
     if (!term->started) {
         guac_client_log(term->client, GUAC_LOG_DEBUG, "Ignoring user input "