GUACAMOLE-564: Merge changes ignoring APC sequences within Guacamole's terminal emulator.
diff --git a/src/terminal/terminal/terminal_handlers.h b/src/terminal/terminal/terminal_handlers.h
index 0b2f9bb..6130d2c 100644
--- a/src/terminal/terminal/terminal_handlers.h
+++ b/src/terminal/terminal/terminal_handlers.h
@@ -186,5 +186,16 @@
  */
 int guac_terminal_ctrl_func(guac_terminal* term, unsigned char c);
 
+/**
+ * Handles terminal control function sequences initiated with "ESC _".
+ *
+ * @param term
+ *     The terminal that received the given character of data.
+ *
+ * @param c
+ *     The character that was received by the given terminal.
+ */
+int guac_terminal_apc(guac_terminal* term, unsigned char c);
+
 #endif
 
diff --git a/src/terminal/terminal_handlers.c b/src/terminal/terminal_handlers.c
index 02e9f9d..afbf20e 100644
--- a/src/terminal/terminal_handlers.c
+++ b/src/terminal/terminal_handlers.c
@@ -367,6 +367,10 @@
             guac_terminal_reset(term);
             break;
 
+        case '_':
+            term->char_handler = guac_terminal_apc;
+            break;
+
         default:
             guac_client_log(term->client, GUAC_LOG_DEBUG,
                     "Unhandled ESC sequence: %c", c);
@@ -1373,3 +1377,19 @@
 
 }
 
+int guac_terminal_apc(guac_terminal* term, unsigned char c) {
+
+    /* xterm does not implement APC functions and neither do we. Look for the
+     * "ESC \" (string terminator) sequence, while ignoring other chars. */
+    static bool escaping = false;
+
+    if (escaping) {
+        if (c == '\\')
+            term->char_handler = guac_terminal_echo;
+        escaping = false;
+    }
+
+    if (c == 0x1B)
+        escaping = true;
+    return 0;
+}