GUACAMOLE-313: Continuously track key press/release.

This commit is contained in:
Michael Jumper 2017-11-26 17:24:49 -08:00
parent ebc731aaf3
commit d39757b4dc
2 changed files with 138 additions and 3 deletions

View File

@ -57,6 +57,9 @@ guaclog_state* guaclog_state_alloc(const char* path) {
/* Associate state with output file */
state->output = output;
/* No keys are initially tracked */
state->active_keys = 0;
return state;
/* Free all allocated data in case of failure */
@ -85,11 +88,108 @@ int guaclog_state_free(guaclog_state* state) {
}
/**
* Adds the given key state to the array of tracked keys. If the key is already
* being tracked, its corresponding entry within the array of tracked keys is
* updated, and the number of tracked keys remains the same. If the key is not
* already being tracked, it is added to the end of the array of tracked keys
* providing there is space available, and the number of tracked keys is
* updated. Failures to add keys will be automatically logged.
*
* @param state
* The Guacamole input log interpreter state being updated.
*
* @param keysym
* The X11 keysym of the key being pressed or released.
*
* @param pressed
* true if the key is being pressed, false if the key is being released.
*
* @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) {
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) {
key->pressed = pressed;
return 0;
}
}
/* 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);
return 1;
}
/* Add key to state */
guaclog_key_state* key = &state->key_states[state->active_keys++];
key->keysym = keysym;
key->pressed = pressed;
return 0;
}
/**
* Removes released keys from the end of the array of tracked keys, such that
* the last key in the array is a pressed key. This function should be invoked
* after changes have been made to the interpreter state, to ensure that the
* array of tracked keys does not grow longer than necessary.
*
* @param state
* The Guacamole input log interpreter state to trim.
*/
static void guaclog_state_trim_keys(guaclog_state* state) {
int i;
/* 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;
}
}
/* No keys are active */
state->active_keys = 0;
}
int guaclog_state_update_key(guaclog_state* state, int keysym, bool pressed) {
/* STUB */
fprintf(state->output, "STUB: keysym=0x%X, pressed=%s\n",
keysym, pressed ? "true" : "false");
int i;
/* Update tracked keysysm state */
guaclog_state_add_key(state, keysym, pressed);
guaclog_state_trim_keys(state);
/* Output new log entries only when keys are pressed */
if (pressed) {
/* STUB: Output raw hex log entry */
for (i = 0; i < state->active_keys; i++) {
if (i != 0)
fprintf(state->output, " ");
guaclog_key_state* key = &state->key_states[i];
fprintf(state->output, "0x%X:%s", key->keysym,
key->pressed ? "*" : " ");
}
/* Terminate log entry with newline */
fprintf(state->output, "\n");
}
return 0;

View File

@ -25,6 +25,29 @@
#include <stdbool.h>
#include <stdio.h>
/**
* The maximum number of keys which may be tracked at any one time before
* newly-pressed keys are ignored.
*/
#define GUACLOG_MAX_KEYS 256
/**
* The current state of a single key.
*/
typedef struct guaclog_key_state {
/**
* The X11 keysym of the key.
*/
int keysym;
/**
* Whether the key is currently pressed (true) or released (false).
*/
bool pressed;
} guaclog_key_state;
/**
* The current state of the Guacamole input log interpreter.
*/
@ -35,6 +58,18 @@ typedef struct guaclog_state {
*/
FILE* output;
/**
* The number of keys currently being tracked within the key_states array.
*/
int active_keys;
/**
* Array of all keys currently being tracked. A key is added to the array
* when it is pressed for the first time. Released keys at the end of the
* array are automatically removed from tracking.
*/
guaclog_key_state key_states[GUACLOG_MAX_KEYS];
} guaclog_state;
/**