You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/01/30 19:08:35 UTC
[07/11] guacamole-server git commit: GUACAMOLE-313: Refactor guaclog
to produce simpler, greppable output.
GUACAMOLE-313: Refactor guaclog to produce simpler, greppable output.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/5b612b85
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/5b612b85
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/5b612b85
Branch: refs/heads/master
Commit: 5b612b856afc29073595d7ce450560b0bff65415
Parents: 86b09c8
Author: Michael Jumper <mj...@apache.org>
Authored: Wed Dec 6 21:25:58 2017 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Fri Jan 26 16:24:45 2018 -0800
----------------------------------------------------------------------
src/guaclog/Makefile.am | 4 +-
src/guaclog/key-name.c | 276 -------------------------------------------
src/guaclog/key-name.h | 50 --------
src/guaclog/keydef.c | 276 +++++++++++++++++++++++++++++++++++++++++++
src/guaclog/keydef.h | 73 ++++++++++++
src/guaclog/state.c | 111 ++++++++++++-----
src/guaclog/state.h | 5 +-
7 files changed, 434 insertions(+), 361 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/Makefile.am
----------------------------------------------------------------------
diff --git a/src/guaclog/Makefile.am b/src/guaclog/Makefile.am
index 5007708..6acced3 100644
--- a/src/guaclog/Makefile.am
+++ b/src/guaclog/Makefile.am
@@ -28,7 +28,7 @@ noinst_HEADERS = \
guaclog.h \
instructions.h \
interpret.h \
- key-name.h \
+ keydef.h \
log.h \
state.h
@@ -37,7 +37,7 @@ guaclog_SOURCES = \
instructions.c \
instruction-key.c \
interpret.c \
- key-name.c \
+ keydef.c \
log.c \
state.c
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/key-name.c
----------------------------------------------------------------------
diff --git a/src/guaclog/key-name.c b/src/guaclog/key-name.c
deleted file mode 100644
index 5ae73b5..0000000
--- a/src/guaclog/key-name.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include "config.h"
-#include "key-name.h"
-#include "log.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-/**
- * A mapping of X11 keysym to its corresponding human-readable name.
- */
-typedef struct guaclog_known_key {
-
- /**
- * The X11 keysym of the key.
- */
- const int keysym;
-
- /**
- * A human-readable name for the key.
- */
- const char* name;
-
-} guaclog_known_key;
-
-/**
- * All known keys.
- */
-const guaclog_known_key known_keys[] = {
- { 0x0020, "Space" },
- { 0xFE03, "AltGr" },
- { 0xFF08, "Backspace" },
- { 0xFF09, "Tab" },
- { 0xFF0B, "Clear" },
- { 0xFF0D, "Return" },
- { 0xFF13, "Pause" },
- { 0xFF1B, "Escape" },
- { 0xFF51, "Left" },
- { 0xFF52, "Up" },
- { 0xFF53, "Right" },
- { 0xFF54, "Down" },
- { 0xFF55, "Page Up" },
- { 0xFF56, "Page Down" },
- { 0xFF63, "Insert" },
- { 0xFF65, "Undo" },
- { 0xFF6A, "Help" },
- { 0xFF80, "Space" },
- { 0xFF8D, "Enter" },
- { 0xFFBD, "Equals" },
- { 0xFFBE, "F1" },
- { 0xFFBF, "F2" },
- { 0xFFC0, "F3" },
- { 0xFFC1, "F4" },
- { 0xFFC2, "F5" },
- { 0xFFC3, "F6" },
- { 0xFFC4, "F7" },
- { 0xFFC5, "F8" },
- { 0xFFC6, "F9" },
- { 0xFFC7, "F10" },
- { 0xFFC8, "F11" },
- { 0xFFC9, "F12" },
- { 0xFFCA, "F13" },
- { 0xFFCB, "F14" },
- { 0xFFCC, "F15" },
- { 0xFFCD, "F16" },
- { 0xFFCE, "F17" },
- { 0xFFCF, "F18" },
- { 0xFFD0, "F19" },
- { 0xFFD1, "F20" },
- { 0xFFD2, "F21" },
- { 0xFFD3, "F22" },
- { 0xFFD4, "F23" },
- { 0xFFD5, "F24" },
- { 0xFFE1, "Shift" },
- { 0xFFE2, "Shift" },
- { 0xFFE3, "Ctrl" },
- { 0xFFE4, "Ctrl" },
- { 0xFFE5, "Caps" },
- { 0xFFE7, "Meta" },
- { 0xFFE8, "Meta" },
- { 0xFFE9, "Alt" },
- { 0xFFEA, "Alt" },
- { 0xFFEB, "Super" },
- { 0xFFEB, "Win" },
- { 0xFFEC, "Super" },
- { 0xFFED, "Hyper" },
- { 0xFFEE, "Hyper" },
- { 0xFFFF, "Delete" }
-};
-
-/**
- * Comparator for the standard bsearch() function which compares an integer
- * keysym against the keysym associated with a guaclog_known_key.
- *
- * @param key
- * The key value being compared against the member. This MUST be the
- * keysym value, passed through typecasting to an intptr_t (NOT a pointer
- * to the int itself).
- *
- * @param member
- * The member within the known_keys array being compared against the given
- * key.
- *
- * @return
- * Zero if the given keysym is equal to that of the given member, a
- * positive value if the given keysym is greater than that of the given
- * member, or a negative value if the given keysym is less than that of the
- * given member.
- */
-static int guaclog_known_key_bsearch_compare(const void* key,
- const void* member) {
-
- int keysym = (int) ((intptr_t) key);
- guaclog_known_key* current = (guaclog_known_key*) member;
-
- /* Compare given keysym to keysym of current member */
- return keysym - current->keysym;
-
-}
-
-/**
- * Searches through the known_keys array of known keys for the name of the key
- * having the given keysym. If found, the name of the keysym is copied into the
- * given buffer, which must be at least GUACLOG_MAX_KEY_NAME_LENGTH bytes long.
- *
- * @param key_name
- * The buffer to copy the key name into, which must be at least
- * GUACLOG_MAX_KEY_NAME_LENGTH.
- *
- * @param keysym
- * The X11 keysym of the key whose name should be stored in
- * key_name.
- *
- * @return
- * The length of the name, in bytes, excluding null terminator, or zero if
- * the key could not be found.
- */
-static int guaclog_locate_key_name(char* key_name, int keysym) {
-
- /* Search through known keys for given keysym */
- guaclog_known_key* found = bsearch((void*) ((intptr_t) keysym),
- known_keys, sizeof(known_keys) / sizeof(known_keys[0]),
- sizeof(known_keys[0]), guaclog_known_key_bsearch_compare);
-
- /* If found, format name and return length of result */
- if (found != NULL)
- return snprintf(key_name, GUACLOG_MAX_KEY_NAME_LENGTH,
- "[ %s ]", found->name);
-
- /* Key not found */
- return 0;
-
-}
-
-/**
- * Produces a name for the key having the given keysym using its corresponding
- * Unicode character. If possible, the name of the keysym is copied into the
- * given buffer, which must be at least GUAC_MAX_KEY_NAME_LENGTH bytes long.
- *
- * @param key_name
- * The buffer to copy the key name into, which must be at least
- * GUACLOG_MAX_KEY_NAME_LENGTH.
- *
- * @param keysym
- * The X11 keysym of the key whose name should be stored in
- * key_name.
- *
- * @return
- * The length of the name, in bytes, excluding null terminator, or zero if
- * a readable name cannot be directly produced via Unicode alone.
- */
-static int guaclog_unicode_key_name(char* key_name, int keysym) {
-
- int i;
- int mask, bytes;
-
- /* Translate only if keysym maps to Unicode */
- if (keysym < 0x00 || (keysym > 0xFF && (keysym & 0xFFFF0000) != 0x01000000))
- return 0;
-
- /* Do not translate whitespace - it will be unreadable */
- if (keysym == 0x20)
- return 0;
-
- int codepoint = keysym & 0xFFFF;
-
- /* Determine size and initial byte mask */
- if (codepoint <= 0x007F) {
- mask = 0x00;
- bytes = 1;
- }
- else if (codepoint <= 0x7FF) {
- mask = 0xC0;
- bytes = 2;
- }
- else if (codepoint <= 0xFFFF) {
- mask = 0xE0;
- bytes = 3;
- }
- else if (codepoint <= 0x1FFFFF) {
- mask = 0xF0;
- bytes = 4;
- }
-
- /* Otherwise, invalid codepoint */
- else {
- *(key_name++) = '?';
- return 1;
- }
-
- /* Offset buffer by size */
- key_name += bytes;
-
- /* Add null terminator */
- *(key_name--) = '\0';
-
- /* Add trailing bytes, if any */
- for (i=1; i<bytes; i++) {
- *(key_name--) = 0x80 | (codepoint & 0x3F);
- codepoint >>= 6;
- }
-
- /* Set initial byte */
- *key_name = mask | codepoint;
-
- /* Done */
- return bytes;
-
-}
-
-int guaclog_key_name(char* key_name, int keysym) {
-
- int name_length;
-
- /* Attempt to translate straight into a Unicode character */
- name_length = guaclog_unicode_key_name(key_name, keysym);
-
- /* If not Unicode, search for name within list of known keys */
- if (name_length == 0)
- name_length = guaclog_locate_key_name(key_name, keysym);
-
- /* Fallback to using hex keysym as name */
- if (name_length == 0)
- name_length = snprintf(key_name, GUACLOG_MAX_KEY_NAME_LENGTH,
- "0x%X", keysym);
-
- /* Truncate name if necessary */
- if (name_length >= GUACLOG_MAX_KEY_NAME_LENGTH) {
- name_length = GUACLOG_MAX_KEY_NAME_LENGTH - 1;
- key_name[name_length] = '\0';
- guaclog_log(GUAC_LOG_DEBUG, "Name for key 0x%X was "
- "truncated.", keysym);
- }
-
- return name_length;
-
-}
-
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/key-name.h
----------------------------------------------------------------------
diff --git a/src/guaclog/key-name.h b/src/guaclog/key-name.h
deleted file mode 100644
index a033b36..0000000
--- a/src/guaclog/key-name.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#ifndef GUACLOG_KEY_NAME_H
-#define GUACLOG_KEY_NAME_H
-
-#include "config.h"
-
-/**
- * The maximum size of the name of any key, in bytes.
- */
-#define GUACLOG_MAX_KEY_NAME_LENGTH 64
-
-/**
- * Copies the name of the key having the given keysym into the given buffer,
- * which must be at least GUACLOG_MAX_KEY_NAME_LENGTH bytes long. This function
- * always succeeds, ultimately resorting to using the hex value of the keysym
- * as the name if no other human-readable name is known.
- *
- * @param key_name
- * The buffer to copy the key name into, which must be at least
- * GUACLOG_MAX_KEY_NAME_LENGTH.
- *
- * @param keysym
- * The X11 keysym of the key whose name should be stored in
- * key_name.
- *
- * @return
- * The length of the name, in bytes, excluding null terminator.
- */
-int guaclog_key_name(char* key_name, int keysym);
-
-#endif
-
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/keydef.c
----------------------------------------------------------------------
diff --git a/src/guaclog/keydef.c b/src/guaclog/keydef.c
new file mode 100644
index 0000000..9616500
--- /dev/null
+++ b/src/guaclog/keydef.c
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "keydef.h"
+#include "log.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * All known keys.
+ */
+const guaclog_keydef known_keys[] = {
+ { 0xFE03, "AltGr" },
+ { 0xFF08, "Backspace" },
+ { 0xFF09, "Tab", "<Tab>" },
+ { 0xFF0B, "Clear" },
+ { 0xFF0D, "Return", "\n" },
+ { 0xFF13, "Pause" },
+ { 0xFF1B, "Escape" },
+ { 0xFF51, "Left" },
+ { 0xFF52, "Up" },
+ { 0xFF53, "Right" },
+ { 0xFF54, "Down" },
+ { 0xFF55, "Page Up" },
+ { 0xFF56, "Page Down" },
+ { 0xFF63, "Insert" },
+ { 0xFF65, "Undo" },
+ { 0xFF6A, "Help" },
+ { 0xFF80, "Space", " " },
+ { 0xFF8D, "Enter", "\n" },
+ { 0xFFBE, "F1" },
+ { 0xFFBF, "F2" },
+ { 0xFFC0, "F3" },
+ { 0xFFC1, "F4" },
+ { 0xFFC2, "F5" },
+ { 0xFFC3, "F6" },
+ { 0xFFC4, "F7" },
+ { 0xFFC5, "F8" },
+ { 0xFFC6, "F9" },
+ { 0xFFC7, "F10" },
+ { 0xFFC8, "F11" },
+ { 0xFFC9, "F12" },
+ { 0xFFCA, "F13" },
+ { 0xFFCB, "F14" },
+ { 0xFFCC, "F15" },
+ { 0xFFCD, "F16" },
+ { 0xFFCE, "F17" },
+ { 0xFFCF, "F18" },
+ { 0xFFD0, "F19" },
+ { 0xFFD1, "F20" },
+ { 0xFFD2, "F21" },
+ { 0xFFD3, "F22" },
+ { 0xFFD4, "F23" },
+ { 0xFFD5, "F24" },
+ { 0xFFE1, "Shift", "" },
+ { 0xFFE2, "Shift", "" },
+ { 0xFFE3, "Ctrl" },
+ { 0xFFE4, "Ctrl" },
+ { 0xFFE5, "Caps" },
+ { 0xFFE7, "Meta" },
+ { 0xFFE8, "Meta" },
+ { 0xFFE9, "Alt" },
+ { 0xFFEA, "Alt" },
+ { 0xFFEB, "Super" },
+ { 0xFFEB, "Win" },
+ { 0xFFEC, "Super" },
+ { 0xFFED, "Hyper" },
+ { 0xFFEE, "Hyper" },
+ { 0xFFFF, "Delete" }
+};
+
+/**
+ * Comparator for the standard bsearch() function which compares an integer
+ * keysym against the keysym associated with a guaclog_keydef.
+ *
+ * @param key
+ * The key value being compared against the member. This MUST be the
+ * keysym value, passed through typecasting to an intptr_t (NOT a pointer
+ * to the int itself).
+ *
+ * @param member
+ * The member within the known_keys array being compared against the given
+ * key.
+ *
+ * @return
+ * Zero if the given keysym is equal to that of the given member, a
+ * positive value if the given keysym is greater than that of the given
+ * member, or a negative value if the given keysym is less than that of the
+ * given member.
+ */
+static int guaclog_keydef_bsearch_compare(const void* key,
+ const void* member) {
+
+ int keysym = (int) ((intptr_t) key);
+ guaclog_keydef* current = (guaclog_keydef*) member;
+
+ /* Compare given keysym to keysym of current member */
+ return keysym - current->keysym;
+
+}
+
+/**
+ * Searches through the known_keys array of known keys for the name of the key
+ * having the given keysym, returning a pointer to the static guaclog_keydef
+ * within the array if found.
+ *
+ * @param keysym
+ * The X11 keysym of the key.
+ *
+ * @return
+ * A pointer to the static guaclog_keydef associated with the given keysym,
+ * or NULL if the key could not be found.
+ */
+static guaclog_keydef* guaclog_get_known_key(int keysym) {
+
+ /* Search through known keys for given keysym */
+ return bsearch((void*) ((intptr_t) keysym),
+ known_keys, sizeof(known_keys) / sizeof(known_keys[0]),
+ sizeof(known_keys[0]), guaclog_keydef_bsearch_compare);
+
+}
+
+/**
+ * Returns a statically-allocated guaclog_keydef representing the key
+ * associated with the given keysym, deriving the name and value of the key
+ * using its corresponding Unicode character.
+ *
+ * @param keysym
+ * The X11 keysym of the key.
+ *
+ * @return
+ * A statically-allocated guaclog_keydef representing the key associated
+ * with the given keysym, or NULL if the given keysym has no corresponding
+ * Unicode character.
+ */
+static guaclog_keydef* guaclog_get_unicode_key(int keysym) {
+
+ static char unicode_keydef_name[8];
+
+ static guaclog_keydef unicode_keydef;
+
+ int i;
+ int mask, bytes;
+
+ /* Translate only if keysym maps to Unicode */
+ if (keysym < 0x00 || (keysym > 0xFF && (keysym & 0xFFFF0000) != 0x01000000))
+ return NULL;
+
+ int codepoint = keysym & 0xFFFF;
+
+ /* Determine size and initial byte mask */
+ if (codepoint <= 0x007F) {
+ mask = 0x00;
+ bytes = 1;
+ }
+ else if (codepoint <= 0x7FF) {
+ mask = 0xC0;
+ bytes = 2;
+ }
+ else if (codepoint <= 0xFFFF) {
+ mask = 0xE0;
+ bytes = 3;
+ }
+ else if (codepoint <= 0x1FFFFF) {
+ mask = 0xF0;
+ bytes = 4;
+ }
+
+ /* Otherwise, invalid codepoint */
+ else
+ return NULL;
+
+ /* Offset buffer by size */
+ char* key_name = unicode_keydef_name + bytes;
+
+ /* Add null terminator */
+ *(key_name--) = '\0';
+
+ /* Add trailing bytes, if any */
+ for (i=1; i<bytes; i++) {
+ *(key_name--) = 0x80 | (codepoint & 0x3F);
+ codepoint >>= 6;
+ }
+
+ /* Set initial byte */
+ *key_name = mask | codepoint;
+
+ /* Return static key definition */
+ unicode_keydef.keysym = keysym;
+ unicode_keydef.name = unicode_keydef.value = unicode_keydef_name;
+ return &unicode_keydef;
+
+}
+
+/**
+ * Copies the given guaclog_keydef into a newly-allocated guaclog_keydef
+ * structure. The resulting guaclog_keydef must eventually be freed through a
+ * call to guaclog_keydef_free().
+ *
+ * @param keydef
+ * The guaclog_keydef to copy.
+ *
+ * @return
+ * A newly-allocated guaclog_keydef structure copied from the given
+ * guaclog_keydef.
+ */
+static guaclog_keydef* guaclog_copy_key(guaclog_keydef* keydef) {
+
+ guaclog_keydef* copy = malloc(sizeof(guaclog_keydef));
+
+ /* Always copy keysym and name */
+ copy->keysym = keydef->keysym;
+ copy->name = strdup(keydef->name);
+
+ /* Copy value only if defined */
+ if (keydef->value != NULL)
+ copy->value = strdup(keydef->value);
+ else
+ copy->value = NULL;
+
+ return copy;
+
+}
+
+guaclog_keydef* guaclog_keydef_alloc(int keysym) {
+
+ guaclog_keydef* keydef;
+
+ /* Check list of known keys first */
+ keydef = guaclog_get_known_key(keysym);
+ if (keydef != NULL)
+ return guaclog_copy_key(keydef);
+
+ /* Failing that, attempt to translate straight into a Unicode character */
+ keydef = guaclog_get_unicode_key(keysym);
+ if (keydef != NULL)
+ return guaclog_copy_key(keydef);
+
+ /* Key not known */
+ guaclog_log(GUAC_LOG_DEBUG, "Definition not found for key 0x%X.", keysym);
+ return NULL;
+
+}
+
+void guaclog_keydef_free(guaclog_keydef* keydef) {
+
+ /* Ignore NULL keydef */
+ if (keydef == NULL)
+ return;
+
+ free(keydef->name);
+ free(keydef->value);
+ free(keydef);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/keydef.h
----------------------------------------------------------------------
diff --git a/src/guaclog/keydef.h b/src/guaclog/keydef.h
new file mode 100644
index 0000000..d0b2720
--- /dev/null
+++ b/src/guaclog/keydef.h
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUACLOG_KEYDEF_H
+#define GUACLOG_KEYDEF_H
+
+#include "config.h"
+
+/**
+ * A mapping of X11 keysym to its corresponding human-readable name.
+ */
+typedef struct guaclog_keydef {
+
+ /**
+ * The X11 keysym of the key.
+ */
+ int keysym;
+
+ /**
+ * A human-readable name for the key.
+ */
+ char* name;
+
+ /**
+ * The value which would be typed in a typical text editor, if any. If the
+ * key is not associated with any typable value, or if the typable value is
+ * not generally useful in an auditing context, this will be NULL.
+ */
+ char* value;
+
+} guaclog_keydef;
+
+/**
+ * Creates a new guaclog_keydef which represents the key having the given
+ * keysym. The resulting guaclog_keydef must eventually be freed through a
+ * call to guaclog_keydef_free().
+ *
+ * @param keysym
+ * The X11 keysym of the key.
+ *
+ * @return
+ * A new guaclog_keydef which represents the key having the given keysym,
+ * or NULL if no such key is known.
+ */
+guaclog_keydef* guaclog_keydef_alloc(int keysym);
+
+/**
+ * Frees all resources associated with the given guaclog_keydef. If the given
+ * guaclog_keydef is NULL, this function has no effect.
+ *
+ * @param keydef
+ * The guaclog_keydef to free, which may be NULL.
+ */
+void guaclog_keydef_free(guaclog_keydef* keydef);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/state.c
----------------------------------------------------------------------
diff --git a/src/guaclog/state.c b/src/guaclog/state.c
index 616d043..4965985 100644
--- a/src/guaclog/state.c
+++ b/src/guaclog/state.c
@@ -18,7 +18,7 @@
*/
#include "config.h"
-#include "key-name.h"
+#include "keydef.h"
#include "log.h"
#include "state.h"
@@ -77,10 +77,16 @@ fail_output_fd:
int guaclog_state_free(guaclog_state* state) {
+ int i;
+
/* Ignore NULL state */
if (state == NULL)
return 0;
+ /* Free keydefs of all tracked keys */
+ for (i = 0; i < state->active_keys; i++)
+ guaclog_keydef_free(state->key_states[i].keydef);
+
/* Close output file */
fclose(state->output);
@@ -100,8 +106,11 @@ int guaclog_state_free(guaclog_state* state) {
* @param state
* The Guacamole input log interpreter state being updated.
*
- * @param keysym
- * The X11 keysym of the key being pressed or released.
+ * @param keydef
+ * The guaclog_keydef of the key being pressed or released. This
+ * guaclog_keydef will automatically be freed along with the guaclog_state
+ * if the key state was successfully added, and must be manually freed
+ * otherwise.
*
* @param pressed
* true if the key is being pressed, false if the key is being released.
@@ -109,14 +118,17 @@ int guaclog_state_free(guaclog_state* state) {
* @return
* Zero if the key state was successfully added, non-zero otherwise.
*/
-static int guaclog_state_add_key(guaclog_state* state, int keysym, bool pressed) {
+static int guaclog_state_add_key(guaclog_state* state, guaclog_keydef* keydef,
+ bool pressed) {
int i;
/* Update existing key, if already tracked */
for (i = 0; i < state->active_keys; i++) {
guaclog_key_state* key = &state->key_states[i];
- if (key->keysym == keysym) {
+ if (key->keydef->keysym == keydef->keysym) {
+ guaclog_keydef_free(key->keydef);
+ key->keydef = keydef;
key->pressed = pressed;
return 0;
}
@@ -125,13 +137,13 @@ static int guaclog_state_add_key(guaclog_state* state, int keysym, bool pressed)
/* If not already tracked, we need space to add it */
if (state->active_keys == GUACLOG_MAX_KEYS) {
guaclog_log(GUAC_LOG_WARNING, "Unable to log key 0x%X: Too many "
- "active keys.", keysym);
+ "active keys.", keydef->keysym);
return 1;
}
/* Add key to state */
guaclog_key_state* key = &state->key_states[state->active_keys++];
- key->keysym = keysym;
+ key->keydef = keydef;
key->pressed = pressed;
return 0;
@@ -152,11 +164,16 @@ static void guaclog_state_trim_keys(guaclog_state* state) {
/* Reset active_keys to contain only up to the last pressed key */
for (i = state->active_keys - 1; i >= 0; i--) {
+
guaclog_key_state* key = &state->key_states[i];
if (key->pressed) {
state->active_keys = i + 1;
return;
}
+
+ /* Free all trimmed states */
+ guaclog_keydef_free(key->keydef);
+
}
/* No keys are active */
@@ -164,44 +181,76 @@ static void guaclog_state_trim_keys(guaclog_state* state) {
}
+/**
+ * Returns whether the current tracked key state represents an in-progress
+ * keyboard shortcut.
+ *
+ * @param state
+ * The Guacamole input log interpreter state to test.
+ *
+ * @return
+ * true if the given state represents an in-progress keyboard shortcut,
+ * false otherwise.
+ */
+static bool guaclog_state_is_shortcut(guaclog_state* state) {
+
+ int i;
+
+ /* We are in a shortcut if at least one key is non-printable */
+ for (i = 0; i < state->active_keys; i++) {
+ guaclog_key_state* key = &state->key_states[i];
+ if (key->keydef->value == NULL)
+ return true;
+ }
+
+ /* All keys are printable - no shortcut */
+ return false;
+
+}
+
int guaclog_state_update_key(guaclog_state* state, int keysym, bool pressed) {
int i;
- /* Update tracked keysysm state */
- guaclog_state_add_key(state, keysym, pressed);
- guaclog_state_trim_keys(state);
+ /* Determine nature of key */
+ guaclog_keydef* keydef = guaclog_keydef_alloc(keysym);
+ if (keydef == NULL)
+ return 0;
- /* Output new log entries only when keys are pressed */
- if (pressed) {
+ /* Update tracked key state */
+ if (guaclog_state_add_key(state, keydef, pressed))
+ guaclog_keydef_free(keydef);
+ else
+ guaclog_state_trim_keys(state);
- /* Compose log entry by inspecting the state of each tracked key */
- for (i = 0; i < state->active_keys; i++) {
+ /* Output key states only for printable keys */
+ if (pressed && keydef->value != NULL) {
- guaclog_key_state* key = &state->key_states[i];
+ if (guaclog_state_is_shortcut(state)) {
- /* Translate keysym into human-readable name */
- char key_name[GUACLOG_MAX_KEY_NAME_LENGTH];
- int name_length = guaclog_key_name(key_name, key->keysym);
+ fprintf(state->output, "<");
- /* If not the final key, omit the name (it was printed earlier) */
- if (i < state->active_keys - 1) {
- memset(key_name, ' ', name_length);
- if (key->pressed)
- key_name[name_length / 2] = '*';
- }
+ /* Compose log entry by inspecting the state of each tracked key */
+ for (i = 0; i < state->active_keys; i++) {
- /* Separate each key by a single space */
- if (i != 0)
- fprintf(state->output, " ");
+ /* Translate keysym into human-readable name */
+ guaclog_key_state* key = &state->key_states[i];
+
+ /* Print name of key */
+ if (i == 0)
+ fprintf(state->output, "%s", key->keydef->name);
+ else
+ fprintf(state->output, "+%s", key->keydef->name);
+
+ }
- /* Print name of key */
- fprintf(state->output, "%s", key_name);
+ fprintf(state->output, ">");
}
- /* Terminate log entry with newline */
- fprintf(state->output, "\n");
+ /* Print the key itself */
+ else
+ fprintf(state->output, "%s", keydef->value);
}
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5b612b85/src/guaclog/state.h
----------------------------------------------------------------------
diff --git a/src/guaclog/state.h b/src/guaclog/state.h
index 0dd2f2f..b476dde 100644
--- a/src/guaclog/state.h
+++ b/src/guaclog/state.h
@@ -21,6 +21,7 @@
#define GUACLOG_STATE_H
#include "config.h"
+#include "keydef.h"
#include <stdbool.h>
#include <stdio.h>
@@ -37,9 +38,9 @@
typedef struct guaclog_key_state {
/**
- * The X11 keysym of the key.
+ * The definition of the key.
*/
- int keysym;
+ guaclog_keydef* keydef;
/**
* Whether the key is currently pressed (true) or released (false).