From 10d5fd5e9759d36baa78cc2f5b57b828c12e0394 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Tue, 16 Oct 2012 15:58:58 +0200 Subject: [PATCH] Add key-handler for ICS Input Box 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 | 75 +++++++++++++++++++++++++++++++------------------ xoptions.c | 91 ++++++++++++++++++++++++++++++++--------------------------- 2 files changed, 97 insertions(+), 69 deletions(-) diff --git a/xboard.c b/xboard.c index 6e38569..3157544 100644 --- 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+ 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) { diff --git a/xoptions.c b/xoptions.c index 26e7d02..2743f97 100644 --- a/xoptions.c +++ b/xoptions.c @@ -50,6 +50,7 @@ extern char *getenv(); #include #include #include +#include #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); -- 1.7.0.4