Add key-handler for ICS Input Box
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 16 Oct 2012 13:58:58 +0000 (15:58 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Tue, 6 Nov 2012 13:13:54 +0000 (14:13 +0100)
In contrast to the X11 code, all intercepted keys are now treated by
the same callback. The ICS Input Box callback triggers on Up, Down and
Return key, and refers to these symbolically.

xboard.c
xoptions.c

index 6e38569..3157544 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -1634,6 +1634,43 @@ SetMenuEnables (Enables *enab)
 }
 
 #ifdef TODO_GTK
+gboolean KeyPressProc(window, eventkey, data)
+     GtkWindow *window;
+     GdkEventKey  *eventkey;
+     gpointer data;
+{
+
+    MoveTypeInProc(eventkey); // pop up for typed in moves
+
+    // handle shift+<number> cases
+    if (eventkey->state & GDK_SHIFT_MASK) {
+        guint keyval;
+
+        gdk_keymap_translate_keyboard_state(NULL, eventkey->hardware_keycode,
+                                           0, eventkey->group,
+                                           &keyval, NULL, NULL, NULL);
+        switch(keyval) {
+            case GDK_1:
+                AskQuestionEvent("Direct command", "Send to chess program:", "", "1");
+                break;
+            case GDK_2:
+                AskQuestionEvent("Direct command", "Send to second chess program:", "", "2");
+                break;
+            default:
+                break;
+        }
+    }
+
+    /* check for other key values */
+    switch(eventkey->keyval) {
+        case GDK_question:
+         AboutGameEvent();
+         break;
+        default:
+         break;
+    }
+    return False;
+}
 void
 KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {   // [HGM] new method of key binding: specify MenuItem(FlipView) in stead of FlipViewProc in translation string
@@ -2128,39 +2165,23 @@ ShiftKeys ()
     return k;
 }
 
-#ifdef TODO_GTK
-static void
-MoveTypeInProc (Widget widget, caddr_t unused, XEvent *event)
+void MoveTypeInProc(eventkey)
+    GdkEventKey  *eventkey;
 {
     char buf[10];
-    KeySym sym;
-    int n = XLookupString(&(event->xkey), buf, 10, &sym, NULL);
-    if ( n == 1 && *buf >= 32 // printable
-        && !(ShiftKeys() & 0x3C) // no Alt, Ctrl
-       ) BoxAutoPopUp (buf);
-}
-#endif
 
-#ifdef TODO_GTK
-static void
-UpKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{   // [HGM] input: let up-arrow recall previous line from history
-    IcsKey(1);
-}
-
-static void
-DownKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{   // [HGM] input: let down-arrow recall next line from history
-    IcsKey(-1);
-}
+    // ingnore if ctrl or alt is pressed
+    if (eventkey->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)) {
+        return;
+    }
 
-static void
-EnterKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
-{
-    IcsKey(0);
+    buf[0]=eventkey->keyval;
+    buf[1]='\0';
+    if (*buf >= 32)        
+       BoxAutoPopUp (buf);
 }
 
-
+#ifdef TODO_GTK
 void
 TempBackwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 {
index 26e7d02..2743f97 100644 (file)
@@ -50,6 +50,7 @@ extern char *getenv();
 #include <cairo/cairo.h>
 #include <cairo/cairo-xlib.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>  
 
 #include "common.h"
 #include "backend.h"
@@ -534,13 +535,30 @@ char *translationTable[] = { // beware: order is essential!
    filterTranslations, gameListTranslations, memoTranslations
 };
 
+static gboolean
+ICSKeyEvent(GtkWidget *widget, GdkEventKey *event)
+{
+    switch(event->keyval) {
+      case GDK_Return: IcsKey(0); return TRUE;
+      case GDK_Up:     IcsKey(1); return TRUE;
+      case GDK_Down:  IcsKey(-1); return TRUE;
+      default: return FALSE;
+    }
+}
+
 void
 AddHandler (Option *opt, int nr)
 {
-#ifdef TODO_GTK
     switch(nr) {
-      case 
+      case 0: 
+      case 1: 
+      case 2: break;
+      case 3: g_signal_connect(opt->handle, "key-press-event", G_CALLBACK (ICSKeyEvent), NULL); break;
+      case 4: 
+      case 5: 
+      case 6: break;
     }
+#ifdef TODO_GTK
     XtOverrideTranslations(opt->handle, XtParseTranslationTable(translationTable[nr]));
 #endif
 }
@@ -614,10 +632,11 @@ PopDown (DialogClass n)
     
     gtk_widget_hide(shells[n]);
     shellUp[n]--; // count rather than clear
+
     if(n == 0 || n >= PromoDlg) {
         gtk_widget_destroy(shells[n]);
         shells[n] = NULL;
-    }    
+    }
 
     if(marked[n]) {
        MarkMenuItem(marked[n], False);
@@ -633,26 +652,37 @@ PopDown (DialogClass n)
     return 1;
 }
 
-gboolean GenericPopDown(w, event, gdata)
+/* GTK callback used when OK/cancel clicked in genericpopup for non-modal dialog */
+gboolean GenericPopDown(w, resptype, gdata)
      GtkWidget *w;
-     GdkEvent  *event;
-     gpointer  gdata; 
+     GtkResponseType  resptype;
+     gpointer  gdata;
 {
-    int dlg = (intptr_t) gdata; /* dialog number dlgnr */
-    
+    DialogClass dlg = (intptr_t) gdata; /* dialog number dlgnr */
+    GtkWidget *sh = shells[dlg];
+
+    currentOption = dialogOptions[dlg];
+
 #ifdef TODO_GTK
 // I guess BrowserDlg will be abandoned, as GTK has a better browser of its own
-    if(shellUp[BrowserDlg] && dlg != BrowserDlg || dialogError) return; // prevent closing dialog when it has an open file-browse daughter
+    if(shellUp[BrowserDlg] && dlg != BrowserDlg || dialogError) return True; // prevent closing dialog when it has an open file-browse daughter
 #else
-    if(browserUp || dialogError && dlg != FatalDlg) return True; // prevent closing dialog when it has an open file-browse daughter
+    if(browserUp || dialogError && dlg != FatalDlg) return True; // prevent closing dialog when it has an open file-browse or error-popup daughter
 #endif
-    GtkWidget *sh = shells[dlg];
-printf("popdown %d\n", dlg);
     shells[dlg] = w; // make sure we pop down the right one in case of multiple instances
-    PopDown(dlg);
+
+    /* OK pressed */    
+    if (resptype == GTK_RESPONSE_ACCEPT) {
+        if (GenericReadout(currentOption, -1)) PopDown(dlg);
+        return TRUE;
+    } else
+    /* cancel pressed */
+    {
+       if(dlg == BoardWindow) ExitEvent(0);
+       PopDown(dlg);
+    }
     shells[dlg] = sh; // restore
-    if(dlg == BoardWindow) ExitEvent(0);
-    return True; /* don't propagate to default handler */
+    return TRUE;
 }
 
 int AppendText(Option *opt, char *s)
@@ -777,27 +807,6 @@ GraphExpose (Option *opt, int x, int y, int w, int h)
  *) &e, (gpointer) opt); // fake expose event
 }
 
-/* GTK callback used when OK/cancel clicked in genericpopup for non-modal dialog */
-void GenericPopUpCallback(w, resptype, gdata)
-     GtkWidget *w;
-     GtkResponseType  resptype;
-     gpointer  gdata;
-{
-    int data = (intptr_t) gdata; /* dialog number dlgnr */
-    DialogClass dlg;
-
-    currentOption = dialogOptions[dlg=data>>16]; data &= 0xFFFF;
-
-    /* OK pressed */    
-    if (resptype == GTK_RESPONSE_ACCEPT) {
-        if (GenericReadout(currentOption, -1)) PopDown(data);
-        return;
-    }
-
-    /* cancel pressed */
-    PopDown(dlg);    
-}
-
 void GenericCallback(GtkWidget *widget, gpointer gdata)
 {
     const gchar *name;
@@ -815,15 +824,13 @@ void GenericCallback(GtkWidget *widget, gpointer gdata)
     sh = shells[dlg]; // make following line a no-op, as we haven't found out what the real shell is yet (breaks multiple popups of same type!)
 #endif
     oldSh = shells[dlg]; shells[dlg] = sh; // bow to reality
-    
-#ifdef TODO_GTK
+
     if (data == 30000) { // cancel
         PopDown(dlg); 
     } else
     if (data == 30001) { // save buttons imply OK
         if(GenericReadout(currentOption, -1)) PopDown(dlg); // calls OK-proc after full readout, but no popdown if it returns false
     } else
-#endif
 
     if(currentCps) {
         name = gtk_button_get_label (GTK_BUTTON(widget));         
@@ -1054,7 +1061,7 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
 
     int i, j, arraysize, left, top, height=999, width=1, boxStart;    
     char def[MSG_SIZ], *msg, engineDlg = (currentCps != NULL && dlgNr != BrowserDlg);
-    
+
     if(dlgNr < PromoDlg && shellUp[dlgNr]) return 0; // already up
 
     if(dlgNr && dlgNr < PromoDlg && shells[dlgNr]) { // reusable, and used before (but popped down)
@@ -1407,8 +1414,8 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent
     }
 
     g_signal_connect (dialog, "response",
-                      G_CALLBACK (GenericPopUpCallback),
-                      (gpointer)(intptr_t) (dlgNr<<16 | i));
+                      G_CALLBACK (GenericPopDown),
+                      (gpointer)(intptr_t) dlgNr);
     g_signal_connect (dialog, "delete-event",
                       G_CALLBACK (GenericPopDown),
                       (gpointer)(intptr_t) dlgNr);