[BRLTTY] BRLTTY with keytable enabled sometimes locks keys

Dave Mielke dave at mielke.cc
Sun Jul 27 20:32:18 EDT 2014


Please test this patch (attached as keyboard-1.patch) to see if it resolves the 
problem.

-- 
Dave Mielke           | 2213 Fox Crescent | The Bible is the very Word of God.
Phone: 1-613-726-0014 | Ottawa, Ontario   | http://Mielke.cc/bible/
EMail: dave at mielke.cc | Canada  K2A 1H7   | http://FamilyRadio.com/
-------------- next part --------------
diff --git a/Programs/keyboard.c b/Programs/keyboard.c
index ecf60a3..6c66bd6 100644
--- a/Programs/keyboard.c
+++ b/Programs/keyboard.c
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include "log.h"
+#include "program.h"
 #include "parse.h"
 #include "bitmask.h"
 
@@ -111,6 +112,18 @@ checkKeyboardProperties (const KeyboardProperties *actual, const KeyboardPropert
   return 1;
 }
 
+static void
+flushKeyEvents (KeyboardInstanceData *kid) {
+  const KeyEventEntry *event = kid->keyEventBuffer;
+
+  while (kid->keyEventCount) {
+    forwardKeyEvent(event->code, event->press);
+    event += 1, kid->keyEventCount -= 1;
+  }
+
+  memset(kid->handledKeysMask, 0, kid->handledKeysSize);
+}
+
 void
 claimKeyboardCommonData (KeyboardCommonData *kcd) {
   kcd->referenceCount += 1;
@@ -119,13 +132,30 @@ claimKeyboardCommonData (KeyboardCommonData *kcd) {
 void
 releaseKeyboardCommonData (KeyboardCommonData *kcd) {
   if (!(kcd->referenceCount -= 1)) {
+    if (kcd->instances) deallocateQueue(kcd->instances);
     free(kcd);
   }
 }
 
+static int
+exitKeyboardInstanceData (void *item, void *data) {
+  KeyboardInstanceData *kid = item;
+
+  flushKeyEvents(kid);
+  return 0;
+}
+
+static void
+exitKeyboardMonitor (void *data) {
+  KeyboardCommonData *kcd = data;
+
+  kcd->stopping = 1;
+  processQueue(kcd->instances, exitKeyboardInstanceData, NULL);
+  releaseKeyboardCommonData(kcd);
+}
+
 int
 startKeyboardMonitor (const KeyboardProperties *properties, KeyEventHandler handleKeyEvent) {
-  int started = 0;
   KeyboardCommonData *kcd;
 
   if ((kcd = malloc(sizeof(*kcd)))) {
@@ -137,13 +167,22 @@ startKeyboardMonitor (const KeyboardProperties *properties, KeyEventHandler hand
     kcd->handleKeyEvent = handleKeyEvent;
     kcd->requiredProperties = *properties;
 
-    if (monitorKeyboards(kcd))  started = 1;
+    if ((kcd->instances = newQueue(NULL, NULL))) {
+      if (monitorKeyboards(kcd)) {
+        onProgramExit("keyboard-monitor", exitKeyboardMonitor, kcd);
+        kcd->stopping = 0;
+        return 1;
+      }
+
+      deallocateQueue(kcd->instances);
+    }
+
     releaseKeyboardCommonData(kcd);
   } else {
     logMallocError();
   }
 
-  return started;
+  return 0;
 }
 
 KeyboardInstanceData *
@@ -155,9 +194,6 @@ newKeyboardInstanceData (KeyboardCommonData *kcd) {
   if ((kid = malloc(size))) {
     memset(kid, 0, size);
 
-    kid->kcd = kcd;
-    claimKeyboardCommonData(kcd);
-
     kid->actualProperties = anyKeyboard;
 
     kid->keyEventBuffer = NULL;
@@ -167,7 +203,14 @@ newKeyboardInstanceData (KeyboardCommonData *kcd) {
     kid->justModifiers = 0;
     kid->handledKeysSize = count;
 
-    return kid;
+    if (enqueueItem(kcd->instances, kid)) {
+      kid->kcd = kcd;
+      claimKeyboardCommonData(kcd);
+
+      return kid;
+    }
+
+    free(kid);
   } else {
     logMallocError();
   }
@@ -177,7 +220,9 @@ newKeyboardInstanceData (KeyboardCommonData *kcd) {
 
 void
 deallocateKeyboardInstanceData (KeyboardInstanceData *kid) {
+  flushKeyEvents(kid);
   if (kid->keyEventBuffer) free(kid->keyEventBuffer);
+  deleteItem(kid->kcd->instances, kid);
   releaseKeyboardCommonData(kid->kcd);
   free(kid);
 }
@@ -186,12 +231,14 @@ void
 handleKeyEvent (KeyboardInstanceData *kid, int code, int press) {
   KeyTableState state = KTS_UNBOUND;
 
-  if ((code >= 0) && (code < keyCodeLimit)) {
-    const KeyValue *kv = &keyCodeMap[code];
+  if (!kid->kcd->stopping) {
+    if ((code >= 0) && (code < keyCodeLimit)) {
+      const KeyValue *kv = &keyCodeMap[code];
 
-    if ((kv->group != KBD_GROUP(SPECIAL)) || (kv->number != KBD_KEY(SPECIAL, Unmapped))) {
-      if ((kv->group == KBD_GROUP(SPECIAL)) && (kv->number == KBD_KEY(SPECIAL, Ignore))) return;
-      state = kid->kcd->handleKeyEvent(kv->group, kv->number, press);
+      if ((kv->group != KBD_GROUP(SPECIAL)) || (kv->number != KBD_KEY(SPECIAL, Unmapped))) {
+        if ((kv->group == KBD_GROUP(SPECIAL)) && (kv->number == KBD_KEY(SPECIAL, Ignore))) return;
+        state = kid->kcd->handleKeyEvent(kv->group, kv->number, press);
+      }
     }
   }
 
@@ -253,16 +300,8 @@ handleKeyEvent (KeyboardInstanceData *kid, int code, int press) {
     }
 
     switch (action) {
-      case WKA_ALL: {
-        const KeyEventEntry *event = kid->keyEventBuffer;
-
-        while (kid->keyEventCount) {
-          forwardKeyEvent(event->code, event->press);
-          event += 1, kid->keyEventCount -= 1;
-        }
-
-        memset(kid->handledKeysMask, 0, kid->handledKeysSize);
-      }
+      case WKA_ALL:
+        flushKeyEvents(kid);
 
       case WKA_CURRENT:
         forwardKeyEvent(code, press);
diff --git a/Programs/keyboard_internal.h b/Programs/keyboard_internal.h
index 7c8bc2d..a233cc6 100644
--- a/Programs/keyboard_internal.h
+++ b/Programs/keyboard_internal.h
@@ -19,6 +19,7 @@
 #ifndef BRLTTY_INCLUDED_KEYBOARD_INTERNAL
 #define BRLTTY_INCLUDED_KEYBOARD_INTERNAL
 
+#include "queue.h"
 #include "ktb_keyboard.h"
 
 #ifdef __cplusplus
@@ -27,6 +28,8 @@ extern "C" {
 
 typedef struct {
   unsigned int referenceCount;
+  unsigned stopping:1;
+  Queue *instances;
   KeyEventHandler *handleKeyEvent;
   KeyboardProperties requiredProperties;
 } KeyboardCommonData;


More information about the BRLTTY mailing list