Add Shift detection
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 18 Oct 2012 11:12:48 +0000 (13:12 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 6 Nov 2012 13:15:09 +0000 (14:15 +0100)
The state of Shift and Ctrl was only probed on button clicks, so it
is now read out of the button-event struct in the relevant button handlers.
For backwad compatibility, they store it in a global, so the routine
ShiftKeys can take them from there.

xboard.c
xoptions.c

index f376da3..5c42dba 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -2097,23 +2097,6 @@ QuitWrapper (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 }
 #endif
 
-int
-ShiftKeys ()
-{   // bassic primitive for determining if modifier keys are pressed
-    int i,j,  k=0;
-#ifdef TODO_GTK
-    long int codes[] = { XK_Meta_L, XK_Meta_R, XK_Control_L, XK_Control_R, XK_Shift_L, XK_Shift_R };
-    char keys[32];
-    XQueryKeymap(xDisplay,keys);
-    for(i=0; i<6; i++) {
-       k <<= 1;
-       j = XKeysymToKeycode(xDisplay, codes[i]);
-       k += ( (keys[j>>3]&1<<(j&7)) != 0 );
-    }
-#endif
-    return k;
-}
-
 void MoveTypeInProc(eventkey)
     GdkEventKey  *eventkey;
 {
index 14e6ff4..ee055f1 100644 (file)
@@ -459,6 +459,36 @@ ICSKeyEvent(GtkWidget *widget, GdkEventKey *event)
     }
 }
 
+int shiftState, controlState;
+
+static gboolean
+TypeInProc (GtkWidget *widget, GdkEventKey *event, gpointer gdata)
+{   // This callback catches key presses on text-entries, and uses <Enter> and <Esc> as synonyms for dialog OK or Cancel
+    // *** kludge alert *** If a dialog does want some other action, like sending the line typed in the text-entry to an ICS,
+    // it should define an OK handler that does so, and returns FALSE to suppress the popdown.
+    int n = (intptr_t) gdata;
+    int dlg = n >> 16;
+    Option *opt;
+    n &= 0xFFFF;
+    opt = &dialogOptions[dlg][n];
+
+    if(opt == icsBox) return ICSKeyEvent(event->keyval); // Intercept ICS Input Box, which needs special treatment
+
+    shiftState = event->state & GDK_SHIFT_MASK;
+    controlState = event->state & GDK_CONTROL_MASK;
+    switch(event->keyval) {
+      case GDK_Return:
+       if(GenericReadout(dialogOptions[dlg], -1)) PopDown(dlg);
+       break;
+      case GDK_Escape:
+       PopDown(dlg);
+       break;
+      default:
+       return FALSE;
+    }
+    return TRUE;
+}
+
 void
 HighlightText (Option *opt, int from, int to, Boolean highlight)
 {
@@ -475,6 +505,12 @@ HighlightText (Option *opt, int from, int to, Boolean highlight)
     gtk_text_buffer_apply_tag_by_name(opt->handle, highlight ? "highlight" : "normal", &start, &end);
 }
 
+int
+ShiftKeys ()
+{   // bassic primitive for determining if modifier keys are pressed
+    return 3*(shiftState != 0) + 0xC*(controlState != 0); // rely on what last mouse button press left us
+}
+
 static gboolean
 MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
 {   // handle mouse clicks on text widgets that need it
@@ -502,6 +538,8 @@ MemoEvent(GtkWidget *widget, GdkEvent *event, gpointer gdata)
        case GDK_BUTTON_PRESS:
            w = bevent->x; h = bevent->y;
            button = bevent->button;
+           shiftState = bevent->state & GDK_SHIFT_MASK;
+           controlState = bevent->state & GDK_CONTROL_MASK;
 // GTK_TODO: is this really the most efficient way to get the character at the mouse cursor???
            gtk_text_view_window_to_buffer_coords(widget, GTK_TEXT_WINDOW_WIDGET, w, h, &x, &y);
            gtk_text_view_get_iter_at_location(widget, &start, x, y);
@@ -760,6 +798,8 @@ GraphEventProc(GtkWidget *widget, GdkEvent *event, gpointer gdata)
        case GDK_BUTTON_PRESS:
            w = bevent->x; h = bevent->y;
            button = bevent->button;
+           shiftState = bevent->state & GDK_SHIFT_MASK;
+           controlState = bevent->state & GDK_CONTROL_MASK;
     }
     button *= f;