[dasher] Gtk2 editor: comment and fix the algorithm for output via XTest



commit fa320ae566b5d114aa161af910856cc75fcbc706
Author: Neil Jerram <neil ossau homelinux net>
Date:   Sun May 4 20:40:07 2014 +0000

    Gtk2 editor: comment and fix the algorithm for output via XTest

 Src/Gtk2/dasher_editor_external_xtest.cpp |   53 ++++++++++++++++++++++------
 1 files changed, 41 insertions(+), 12 deletions(-)
---
diff --git a/Src/Gtk2/dasher_editor_external_xtest.cpp b/Src/Gtk2/dasher_editor_external_xtest.cpp
index efb7a77..a342cd9 100644
--- a/Src/Gtk2/dasher_editor_external_xtest.cpp
+++ b/Src/Gtk2/dasher_editor_external_xtest.cpp
@@ -37,7 +37,7 @@ dasher_editor_external_output(DasherEditor *pSelf, const gchar *szText, int iOff
   KeyCode code;  
   
   if(szText[0] == '\n') {
-    // If it's a nreline, we want to mimic an enter press rather than a raw newline
+    // If it's a newline, we want to mimic an enter press rather than a raw newline
     code = XKeysymToKeycode(dpy, XK_Return);
     if(code != 0) {
       XTestFakeKeyEvent(dpy, code, True, CurrentTime);
@@ -50,15 +50,46 @@ dasher_editor_external_output(DasherEditor *pSelf, const gchar *szText, int iOff
     // gunichar is a 32 bit data type for UTF32 (aka UCS4) encoded unicodeX
     gunichar *wideoutput = g_utf8_to_ucs4(szText, -1, NULL, &numoutput, NULL);
 
+    // Get the X server's keycode value range.
+    XDisplayKeycodes(dpy, &min, &max);
+
     for(int i = 0; i < numoutput; i++) {
 
-      // Erm - this makes no sense
-      int modifiedkey = (i + 1) % 10;
+      // In the string of text that we're outputting, we need first to
+      // convert each character to a X keysym, then fake a keycode
+      // event that the X server will interpret as the desired keysym.
+      //
+      // For the first part, we take advantage of the fact that X
+      // understands a regular mapping of Unicode code points <
+      // 0x1000000 to keysym values: the keysym value is the Unicode
+      // code point + 0x1000000.
+      // (Ref. http://www.cl.cam.ac.uk/~mgk25/ucs/keysym2ucs.c)
+      //
+      // For the second part, we reprogram the X server's keycode to
+      // keysym mapping so that a known keycode will generate each
+      // keysym that we want.  This is actually a pretty horrible
+      // hack, because who knows what other X programs might be
+      // relying on the keycodes that we're reprogramming, or making
+      // its own hacky changes to the keyboard mapping at the same
+      // time?  But we try to reduce the hackiness by using the top
+      // ten keycode values in the X server's range - in the hope that
+      // those might not be being used by other applications.
+
+      // Choose which keycode we're going to appropriate for this
+      // iteration.
+      code = (max - 1 - (i % 10));
+
+      // If we've used the whole set of keycodes and are looping round
+      // to use the first of them again, sleep a bit first to ensure
+      // that the intended client has had time to see and process the
+      // X events, before we go changing the keyboard mapping again.
+      if (i && !(i % 10)) {
+       usleep(200000);
+      }
 
       if(wideoutput[i] < 0x01000000) {
 
-       // See http://wiki.x.org/wiki/KeySyms for the logic behind this
-       // tranlation
+       // Convert Unicode code point to keysym value.
        wideoutput[i] = wideoutput[i] | 0x01000000;
 
        // TODO: Please see
@@ -67,22 +98,20 @@ dasher_editor_external_output(DasherEditor *pSelf, const gchar *szText, int iOff
        // with upper/lower case on some X displays I'm tempted to say
        // that the XTest stuff is just broken, and require some GNOME
        // a11y support for direct entry...
-       
-       XDisplayKeycodes(dpy, &min, &max);
-       
+
        // Returns the keyboard mapping for the current display - numcodes is the 
        keysym = XGetKeyboardMapping(dpy, min, max - min + 1, &numcodes);
-       
+
        // Reprogramme the keyboard map to use the new keysym
-       keysym[(max - min - modifiedkey - 1) * numcodes] = wideoutput[i];
+       keysym[(code - min) * numcodes] = wideoutput[i];
        XChangeKeyboardMapping(dpy, min, numcodes, keysym, (max - min));
        XSync(dpy, true);
-       
+
        // Delete the old keymap
        XFree(keysym);
+
        // There's no way whatsoever that this could ever possibly
        // be guaranteed to work (ever), but it does.
-       code = (max - modifiedkey - 1);
        if(code != 0) {
          XTestFakeKeyEvent(dpy, code, True, CurrentTime);
          XSync(dpy, true);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]