From 0a3919ff10a347a8d840f75fd2c816efe52e5098 Mon Sep 17 00:00:00 2001 From: H.G. Muller Date: Sun, 14 Oct 2012 22:00:14 +0200 Subject: [PATCH] Transfer most available gtk-xt code to xoptions.c GenericPopUp and PopDown are grafted from gtk-xt into gtk2. The version compiles, but segfaults before doing anything, with error messages about unexpected cases in GenericPopup for Graph and PopUp Options of the main board. The spin options need special treatment in GetWidgtText. --- Makefile.am | 2 +- common.h | 7 + dialogs.h | 3 +- xboard.c | 54 +++-- xboard.h | 4 +- xengineoutput.c | 14 +- xgamelist.c | 2 + xgamelist.h | 2 + xhistory.c | 4 +- xoptions.c | 740 +++++++++++++++++++++++++++++++++++++++++++++++-------- xtimer.c | 98 ++++---- 11 files changed, 750 insertions(+), 180 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5e1b810..3cb4956 100644 --- a/Makefile.am +++ b/Makefile.am @@ -52,7 +52,7 @@ if withGTK endif if withXaw xboard_SOURCES = $(backendsources) $(Xsources) - headers = -I xaw + headers = -I xaw -DX11 endif ### diff --git a/common.h b/common.h index c881ca4..71f6c49 100644 --- a/common.h +++ b/common.h @@ -81,7 +81,14 @@ int pclose(FILE *); #endif #else +#ifdef X11 #include +#else +typedef char Boolean; +typedef char *String; +#define True 1 +#define False 0 +#endif #endif #endif diff --git a/dialogs.h b/dialogs.h index 09d66a5..739dc18 100644 --- a/dialogs.h +++ b/dialogs.h @@ -95,7 +95,8 @@ #define W_MENUB 26 #define W_DROP 27 // drop (popup) menu - +#define CHECK (void *) 1 +#define RADIO (void *) 2 typedef enum { // identifier of dialogs done by GenericPopup TransientDlg=0, // transient: grabs mouse events and is destroyed at pop-down (so other dialog can use this ID next time) diff --git a/xboard.c b/xboard.c index 8270d52..2857317 100644 --- a/xboard.c +++ b/xboard.c @@ -63,6 +63,7 @@ #include #include #include +#include #if !OMIT_SOCKETS # if HAVE_SYS_SOCKET_H @@ -290,6 +291,7 @@ XtAppContext appContext; #else void *shellWidget, *formWidget, *boardWidget, *titleWidget, *dropMenu, *menuBarWidget; void *appContext; +GtkWidget *mainwindow; #endif Option *optList; // contains all widgets of main window char *layoutName; @@ -635,13 +637,7 @@ CatchDeleteWindow (Widget w, String procname) void BoardToTop () { -#ifdef TODO_GTK - Arg args[16]; - XtSetArg(args[0], XtNiconic, False); - XtSetValues(shellWidget, args, 1); - - XtPopup(shellWidget, XtGrabNone); /* Raise if lowered */ -#endif + gtk_window_present(GTK_WINDOW(mainwindow)); } //--------------------------------------------------------------------------------------------------------- @@ -1076,12 +1072,12 @@ main (int argc, char **argv) #ifdef TODO_GTK XSetWindowAttributes window_attributes; Arg args[16]; - Dimension boardWidth, boardHeight, w, h; #else - int boardWidth, boardHeight, w, h; #endif + Dimension boardWidth, boardHeight, w, h; char *p; int forceMono = False; + GError *gtkerror=NULL; srandom(time(0)); // [HGM] book: make random truly random @@ -1099,6 +1095,9 @@ main (int argc, char **argv) exit(0); } + /* set up GTK */ + gtk_init (&argc, &argv); + programName = strrchr(argv[0], '/'); if (programName == NULL) programName = argv[0]; @@ -1106,10 +1105,9 @@ main (int argc, char **argv) programName++; #ifdef ENABLE_NLS - XtSetLanguageProc(NULL, NULL, NULL); - if (appData.debugMode) { - fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL)); - } +// if (appData.debugMode) { +// fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL)); +// } bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); @@ -1156,6 +1154,12 @@ main (int argc, char **argv) setbuf(debugFP, NULL); } +#if ENABLE_NLS + if (appData.debugMode) { + fprintf(debugFP, "locale = %s\n", setlocale(LC_ALL, NULL)); + } +#endif + /* [HGM,HR] make sure board size is acceptable */ if(appData.NrFiles > BOARD_FILES || appData.NrRanks > BOARD_RANKS ) @@ -1171,6 +1175,16 @@ main (int argc, char **argv) InitPosition(FALSE); #ifdef TODO_GTK + /* GTK */ + builder = gtk_builder_new(); + filename = get_glade_filename ("mainboard.glade"); + if(! gtk_builder_add_from_file (builder, filename, >kerror) ) + { + if(gtkerror) + printf ("Error: %d %s\n",gtkerror->code,gtkerror->message); + } + mainwindow = GTK_WIDGET(gtk_builder_get_object (builder, "mainwindow")); + shellWidget = XtAppInitialize(&appContext, "XBoard", shellOptions, XtNumber(shellOptions), @@ -1225,6 +1239,14 @@ main (int argc, char **argv) DisplayHeight(xDisplay, xScreen) < szd->minScreenSize) { szd++; } +#else + GdkScreen *screen = gtk_window_get_screen(GTK_WINDOW(mainwindow)); + guint screenwidth = gdk_screen_get_width(screen); + guint screenheight = gdk_screen_get_height(screen); + while (screenwidth < szd->minScreenSize || + screenheight < szd->minScreenSize) { + szd++; + } #endif if (szd->name == NULL) szd--; appData.boardSize = strdup(szd->name); // [HGM] settings: remember name for saving settings @@ -1452,9 +1474,11 @@ main (int argc, char **argv) // XtSetKeyboardFocus(shellWidget, formWidget); #ifdef TODO_GTK XSetInputFocus(xDisplay, XtWindow(formWidget), RevertToPointerRoot, CurrentTime); - - XtAppMainLoop(appContext); #endif + + /* check for GTK events and process them */ + gtk_main(); + if (appData.debugMode) fclose(debugFP); // [DM] debug return 0; } diff --git a/xboard.h b/xboard.h index 5a7b25e..3527343 100644 --- a/xboard.h +++ b/xboard.h @@ -133,6 +133,7 @@ typedef struct { void NewTagsPopup P((char *text, char *msg)); int AppendText P((Option *opt, char *s)); void NewCommentPopup P((char *title, char *text, int index)); +#ifdef TODO_GTK void CatchDeleteWindow(Widget w, String procname); void GenericPopDown P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SetFocus(Widget w, XtPointer data, XEvent *event, Boolean *b); // from xoptions.c @@ -145,6 +146,7 @@ void GenericMenu P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); // from xengineoutput.c void SelectPV P((Widget w, XEvent * event, String * params, Cardinal * nParams)); void StopPV P((Widget w, XEvent * event, String * params, Cardinal * nParams)); +#endif extern char memoTranslations[]; @@ -159,7 +161,7 @@ extern Atom wm_delete_window; extern GC coordGC; extern Dimension textHeight; // of message widget in board window #else -extern void *shells[]; +extern GtkWidget *shells[]; #endif extern int dialogError; extern int squareSize; diff --git a/xengineoutput.c b/xengineoutput.c index f03b870..b4e1ce8 100644 --- a/xengineoutput.c +++ b/xengineoutput.c @@ -48,6 +48,8 @@ extern char *getenv(); # include #endif +#include + #include "common.h" #include "frontend.h" #include "backend.h" @@ -81,12 +83,12 @@ static Pixmap icons[8]; // [HGM] this front-end array translates back-end icon i static Widget memoWidget; #endif +#ifdef TODO_GTK static void ReadIcon (char *pixData[], int iconNr, Widget w) { int r; -#ifdef TODO_GTK if ((r=XpmCreatePixmapFromData(xDisplay, XtWindow(w), pixData, &(icons[iconNr]), @@ -94,8 +96,8 @@ ReadIcon (char *pixData[], int iconNr, Widget w) fprintf(stderr, _("Error %d loading icon image\n"), r); exit(1); } -#endif } +#endif void InitEngineOutput (Option *opt, Option *memo2) @@ -156,10 +158,10 @@ Shift: select-start() extend-end() SelectPV(1) \n \ Any: select-start() extend-end() SelectPV(0) \n \ : StopPV() \n"; +#ifdef TODO_GTK void SelectPV (Widget w, XEvent * event, String * params, Cardinal * nParams) { // [HGM] pv: translate click to PV line, and load it for display -#ifdef TODO_GTK String val; int start, end; XawTextPosition index, dummy; @@ -176,19 +178,19 @@ SelectPV (Widget w, XEvent * event, String * params, Cardinal * nParams) XawTextSetSelection( w, start, end ); highTextStart[currentPV] = start; highTextEnd[currentPV] = end; } -#endif } +#endif +#ifdef TODO_GTK void StopPV (Widget w, XEvent * event, String * params, Cardinal * nParams) { // [HGM] pv: on right-button release, stop displaying PV -#ifdef TODO_GTK XawTextUnsetSelection( w ); highTextStart[currentPV] = highTextEnd[currentPV] = 0; UnLoadPV(); XtCallActionProc(w, "beginning-of-file", event, NULL, 0); -#endif } +#endif //------------------------- Ctrl-C copying of memo texts --------------------------- diff --git a/xgamelist.c b/xgamelist.c index 82e43bf..b2f5ade 100644 --- a/xgamelist.c +++ b/xgamelist.c @@ -43,6 +43,8 @@ extern char *getenv(); # include #endif +#include + #include "common.h" #include "backend.h" #include "xboard.h" diff --git a/xgamelist.h b/xgamelist.h index fa7b41a..c78e736 100644 --- a/xgamelist.h +++ b/xgamelist.h @@ -23,9 +23,11 @@ #ifndef XB_XGAMELIST #define XB_XGAMELIST +#ifdef TODO_GTK void LoadSelectedProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SetFilterProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +#endif #endif /* XB_XGAMELIST */ diff --git a/xhistory.c b/xhistory.c index ca26228..4d0afe8 100644 --- a/xhistory.c +++ b/xhistory.c @@ -85,14 +85,14 @@ char historyTranslations[] = ": select-start() \n \ : extend-end() SelectMove() \n"; +#ifdef TODO_GTK void SelectMove (Widget w, XEvent * event, String * params, Cardinal * nParams) { -#ifdef TODO_GTK XawTextPosition index, dummy; XawTextGetSelectionPos(w, &index, &dummy); FindMoveByCharIndex( index ); // [HGM] also does the actual moving to it, now -#endif } +#endif diff --git a/xoptions.c b/xoptions.c index 9d4f122..b771b4d 100644 --- a/xoptions.c +++ b/xoptions.c @@ -49,6 +49,7 @@ extern char *getenv(); #include #include +#include #include "common.h" #include "backend.h" @@ -68,8 +69,11 @@ extern char *getenv(); // [HGM] the following code for makng menu popups was cloned from the FileNamePopUp routines +#ifdef TODO_GTK static Widget previous = NULL; +#endif static Option *currentOption; +static Boolean browserUp; void UnCaret () @@ -85,10 +89,10 @@ UnCaret () #endif } +#ifdef TODO_GTK void SetFocus (Widget w, XtPointer data, XEvent *event, Boolean *b) { -#ifdef TODO_GTK Arg args[2]; char *s; int j; @@ -102,8 +106,8 @@ SetFocus (Widget w, XtPointer data, XEvent *event, Boolean *b) XtSetValues(w, args, j); XtSetKeyboardFocus((Widget) data, w); previous = w; -#endif } +#endif void BoardFocus () @@ -144,23 +148,81 @@ MarkMenuItem (char *menuRef, int state) #endif } +void GetWidgetTextGTK(GtkWidget *w, char **buf) +{ + GtkTextIter start; + GtkTextIter end; + + if (GTK_IS_TEXT_BUFFER(w)) { + gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(w), &start); + gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(w), &end); + *buf = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(w), &start, &end, FALSE); + } + else { + printf("error in GetWidgetText, invalid widget\n"); + *buf = NULL; + } +} + void GetWidgetText (Option *opt, char **buf) { -#ifdef TODO_GTK - Arg arg; - XtSetArg(arg, XtNstring, buf); - XtGetValues(opt->handle, &arg, 1); -#endif + int x; + static char val[12]; + switch(opt->type) { + case Fractional: + case FileName: + case PathName: + case TextBox: GetWidgetTextGTK((GtkWidget *) opt->handle, buf); break; + case Spin: + x = gtk_spin_button_get_value (GTK_SPIN_BUTTON(opt->handle)); + snprintf(val, 12, "%d", x); *buf = val; + break; + default: + printf("unexpected case (%d) in GetWidgetText\n", opt->type); + *buf = NULL; + } +} + +void SetSpinValue(Option *opt, int val, int n) +{ + if (opt->type == Spin) + { + if (val == -1) + gtk_widget_set_sensitive(opt->handle, FALSE); + else + { + gtk_widget_set_sensitive(opt->handle, TRUE); + gtk_spin_button_set_value(opt->handle, val); + } + } + else + printf("error in SetSpinValue, unknown type %d\n", opt->type); +} + +void SetWidgetTextGTK(GtkWidget *w, char *text) +{ + if (!GTK_IS_TEXT_BUFFER(w)) { + printf("error: SetWidgetTextGTK arg is not a GtkTextBuffer\n"); + return; + } + gtk_text_buffer_set_text(GTK_TEXT_BUFFER(w), text, -1); } void SetWidgetText (Option *opt, char *buf, int n) { + switch(opt->type) { + case Fractional: + case FileName: + case PathName: + case TextBox: SetWidgetTextGTK((GtkWidget *) opt->handle, buf); break; + case Spin: SetSpinValue(opt, atoi(buf), n); break; + default: + printf("unexpected case (%d) in GetWidgetText\n", opt->type); + } #ifdef TODO_GTK - Arg arg; - XtSetArg(arg, XtNstring, buf); - XtSetValues(opt->handle, &arg, 1); +// focus is automatic in GTK? if(n >= 0) SetFocus(opt->handle, shells[n], NULL, False); #endif } @@ -308,6 +370,7 @@ SetIconName (DialogClass dlg, char *name) #endif } +#ifdef TODO_GTK static void CheckCallback (Widget ww, XtPointer client_data, XEvent *event, Boolean *b) { @@ -319,11 +382,12 @@ CheckCallback (Widget ww, XtPointer client_data, XEvent *event, Boolean *b) GetWidgetState(opt, &s); SetWidgetState(opt, !s); } +#endif +#ifdef TODO_GTK static void SpinCallback (Widget w, XtPointer client_data, XtPointer call_data) { -#ifdef TODO_GTK String name, val; Arg args[16]; char buf[MSG_SIZ], *p; @@ -352,38 +416,32 @@ SpinCallback (Widget w, XtPointer client_data, XtPointer call_data) } else return; snprintf(buf, MSG_SIZ, "%d", j); SetWidgetText(opt, buf, TransientDlg); -#endif } +#endif -static void -ComboSelect (Widget w, caddr_t addr, caddr_t index) // callback for all combo items +void ComboSelect(GtkWidget *widget, gpointer addr) { -#ifdef TODO_GTK - Arg args[16]; - Option *opt = dialogOptions[((intptr_t)addr)>>24]; // applicable option list - int i = ((intptr_t)addr)>>16 & 255; // option number - int j = 0xFFFF & (intptr_t) addr; + Option *opt = dialogOptions[((intptr_t)addr)>>8]; // applicable option list + gint i = ((intptr_t)addr) & 255; // option number + gint g; - values[i] = j; // store selected value in Option struct, for retrieval at OK + g = gtk_combo_box_get_active(GTK_COMBO_BOX(widget)); + values[i] = g; // store in temporary, for transfer at OK +#if TODO_GTK +// Note: setting text on button is probably automatic +// Is this still needed? Could be all comboboxes that needed a callbak are now listboxes! +#endif if(opt[i].type == Graph || opt[i].min & COMBO_CALLBACK && (!currentCps || shellUp[BrowserDlg])) { ((ButtonCallback*) opt[i].target)(i); return; } - - if(opt[i].min & NO_GETTEXT) - XtSetArg(args[0], XtNlabel, ((char**)opt[i].choice)[j]); - else - XtSetArg(args[0], XtNlabel, _(((char**)opt[i].choice)[j])); - - XtSetValues(opt[i].handle, args, 1); -#endif } +#ifdef TODO_GTK Widget CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n) { -#ifdef TODO_GTK int j=0; Widget entry; Arg args[16]; @@ -394,15 +452,13 @@ CreateMenuItem (Widget menu, char *msg, XtCallbackProc CB, int n) entry = XtCreateManagedWidget("item", smeBSBObjectClass, menu, args, j+1); XtAddCallback(entry, XtNcallback, CB, (caddr_t)(intptr_t) n); return entry; -#else - return NULL; -#endif } +#endif +#ifdef TODO_GTK static Widget CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def) { // fromList determines if the item texts are taken from a list of strings, or from a menu table -#ifdef TODO_GTK int i; Widget menu, entry; Arg arg; @@ -424,11 +480,54 @@ CreateComboPopup (Widget parent, Option *opt, int n, int fromList, int def) } } return menu; +} #else - return NULL; -#endif +static void +MenuSelect (gpointer addr) // callback for all combo items +{ + Option *opt = dialogOptions[((intptr_t)addr)>>24]; // applicable option list + int i = ((intptr_t)addr)>>16 & 255; // option number + int j = 0xFFFF & (intptr_t) addr; + + values[i] = j; // store selected value in Option struct, for retrieval at OK + ((ButtonCallback*) opt[i].target)(i); } +static GtkWidget * +CreateMenuPopup (Option *opt, int n, int def) +{ // fromList determines if the item texts are taken from a list of strings, or from a menu table + int i; + GtkWidget *menu, *entry; + MenuItem *mb = (MenuItem *) opt->choice; + + menu = gtk_menu_new(); +// menu = XtCreatePopupShell(opt->name, simpleMenuWidgetClass, parent, NULL, 0); + for (i=0; 1; i++) + { + char *msg = mb[i].string; + if(!msg) break; + if(strcmp(msg, "----")) { // + if(!(opt->min & NO_GETTEXT)) msg = _(msg); + if(mb[i].handle) { + entry = gtk_check_menu_item_new_with_label(msg); // should be used for items that can be checkmarked + if(mb[i].handle == RADIO) gtk_check_menu_item_set_draw_as_radio(entry, True); + } else + entry = gtk_menu_item_new_with_label(msg); + gtk_signal_connect_object (GTK_OBJECT (entry), "activate", GTK_SIGNAL_FUNC(MenuSelect), (gpointer) (n<<16)+i); + gtk_widget_show(entry); + } else entry = gtk_separator_menu_item_new(); + gtk_menu_append(GTK_MENU (menu), entry); +//CreateMenuItem(menu, opt->min & NO_GETTEXT ? msg : _(msg), (XtCallbackProc) ComboSelect, (n<<16)+i); + mb[i].handle = (void*) entry; // save item ID, for enabling / checkmarking +// if(i==def) { +// XtSetArg(arg, XtNpopupOnEntry, entry); +// XtSetValues(menu, &arg, 1); +// } + } + return menu; +} +#endif + char moveTypeInTranslations[] = "Return: TypeInProc(1) \n" "Escape: TypeInProc(0) \n"; @@ -442,8 +541,7 @@ char *translationTable[] = { // beware: order is essential! filterTranslations, gameListTranslations, memoTranslations }; -void * shells[NrOfDialogs]; - +void AddHandler (Option *opt, int nr) { #ifdef TODO_GTK @@ -455,11 +553,7 @@ AddHandler (Option *opt, int nr) // cloned from Engine Settings dialog (and later merged with it) -#ifdef TODO_GTK -Widget shells[NrOfDialogs]; -#else -void *shells[NrOfDialogs]; -#endif +GtkWidget *shells[NrOfDialogs]; DialogClass parents[NrOfDialogs]; WindowPlacement *wp[NrOfDialogs] = { // Beware! Order must correspond to DialogClass enum NULL, &wpComment, &wpTags, NULL, NULL, NULL, NULL, &wpMoveHistory, &wpGameList, &wpEngineOutput, &wpEvalGraph, @@ -500,14 +594,38 @@ RaiseWindow (DialogClass dlg) #endif } +/* Sets a check box on (True) or off (False) in the menu */ +void SetCheckMenuItemActive(gchar *name, int menuDlgNr, gboolean active) +{ +#ifdef TODO_GTK +// This doesn't work anymore, as we don't use builder + gchar menuItemName[50]; + + if (name != NULL) + strcpy(menuItemName, name); + else + GetMenuItemName(menuDlgNr, menuItemName); + + if (strcmp(menuItemName, "") == 0) return; + + GtkCheckMenuItem *chk; + chk = GTK_CHECK_MENU_ITEM(gtk_builder_get_object(GTK_BUILDER(builder), menuItemName)); + if (chk == NULL) { + printf("Error: failed to get check menu item %s from builder\n", menuItemName); + return; + } + chk->active = active; // set the check box without emitting any signals +#endif +} + int PopDown (DialogClass n) -{ // pops down any dialog created by GenericPopUp (or returns False if it wasn't up), unmarks any associated marked menu +{ + //Arg args[10]; + + if (!shellUp[n] || !shells[n]) return 0; #ifdef TODO_GTK - int j; - Arg args[10]; - Dimension windowH, windowW; Position windowX, windowY; - if (!shellUp[n] || !shells[n]) return 0; +// Not sure this is still used if(n && wp[n]) { // remember position j = 0; XtSetArg(args[j], XtNx, &windowX); j++; @@ -520,47 +638,66 @@ PopDown (DialogClass n) wp[n]->width = windowW; wp[n]->height = windowH; } - previous = NULL; - XtPopdown(shells[n]); +#endif + + gtk_widget_hide(shells[n]); shellUp[n]--; // count rather than clear - if(n == 0 || n >= PromoDlg) XtDestroyWidget(shells[n]), shells[n] = NULL; + if(n == 0 || n >= PromoDlg) { + gtk_widget_destroy(shells[n]); + shells[n] = NULL; + } +#ifdef TODO_GTK if(marked[n]) { MarkMenuItem(marked[n], False); marked[n] = NULL; } - if(!n && n != BrowserDlg) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now +#else + // when popping down uncheck the check box of the menu item + SetCheckMenuItemActive(NULL, n, False); +#endif + if(!n) currentCps = NULL; // if an Engine Settings dialog was up, we must be popping it down now currentOption = dialogOptions[TransientDlg]; // just in case a transient dialog was up (to allow its check and combo callbacks to work) - RaiseWindow(parents[n]); - if(parents[n] == BoardWindow) XtSetKeyboardFocus(shellWidget, formWidget); +#ifdef TODO_GTK + RaiseWindow(parents[n]); // automatic in GTK? + if(parents[n] == BoardWindow) XtSetKeyboardFocus(shellWidget, formWidget); // also automatic??? #endif return 1; } +gboolean GenericPopDown(w, event, gdata) + GtkWidget *w; + GdkEvent *event; + gpointer gdata; +{ + int dlg = (intptr_t) gdata; /* dialog number dlgnr */ + #ifdef TODO_GTK -void -GenericPopDown (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ // to cause popdown through a translation (Delete Window button!) - int dlg = atoi(prms[0]); - Widget sh = shells[dlg]; +// 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 - shells[dlg] = w; +#else + if(browserUp || dialogError) return True; // prevent closing dialog when it has an open file-browse 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); shells[dlg] = sh; // restore + if(dlg == BoardWindow) ExitEvent(0); + return True; /* don't propagate to default handler */ } -#endif -int -AppendText (Option *opt, char *s) -{ - int len; -#ifdef TODO_GTK - XawTextBlock t; +int AppendText(Option *opt, char *s) +{ char *v; - GetWidgetText(opt, &v); + int len; + GtkTextIter end; + + GetWidgetTextGTK(opt->handle, &v); len = strlen(v); - t.ptr = s; t.firstPos = 0; t.length = strlen(s); t.format = XawFmt8Bit; - XawTextReplace(opt->handle, len, len, &t); -#endif + g_free(v); + gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(opt->handle), &end); + gtk_text_buffer_insert(opt->handle, &end, s, -1); + return len; } @@ -586,20 +723,20 @@ SetColor (char *colorName, Option *box) #endif } +#ifdef TODO_GTK void ColorChanged (Widget w, XtPointer data, XEvent *event, Boolean *b) { // for detecting a typed change in color char buf[10]; -#ifdef TODO_GTK if ( (XLookupString(&(event->xkey), buf, 2, NULL, NULL) == 1) && *buf == '\r' ) RefreshColor((int)(intptr_t) data, 0); -#endif } +#endif +#ifdef TODO_GTK static void GraphEventProc(Widget widget, caddr_t client_data, XEvent *event) { // handle expose and mouse events on Graph widget -#ifdef TODO_GTK Dimension w, h; Arg args[16]; int j, button=10, f=1, sizing=0; @@ -664,8 +801,8 @@ GraphEventProc(Widget widget, caddr_t client_data, XEvent *event) XtPopupSpringLoaded(opt->handle); } XSync(xDisplay, False); -#endif } +#endif void GraphExpose (Option *opt, int x, int y, int w, int h) @@ -678,42 +815,68 @@ GraphExpose (Option *opt, int x, int y, int w, int h) #endif } -static void -GenericCallback (Widget w, XtPointer client_data, XtPointer call_data) -{ // all Buttons in a dialog (including OK, cancel) invoke this -#ifdef TODO_GTK - String name; - Arg args[16]; - char buf[MSG_SIZ]; - int data = (intptr_t) client_data; +/* 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; + char buf[MSG_SIZ]; + int data = (intptr_t) gdata; DialogClass dlg; - Widget sh = XtParent(XtParent(XtParent(w))), oldSh; +#ifdef TODO_GTK + GtkWidget *sh = XtParent(XtParent(XtParent(w))), *oldSh; +#else + GtkWidget *sh, *oldSh; +#endif currentOption = dialogOptions[dlg=data>>16]; data &= 0xFFFF; +#ifndef TODO_GTK + 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 && dlg != BrowserDlg) { - XtSetArg(args[0], XtNlabel, &name); - XtGetValues(w, args, 1); + if(currentCps) { + name = gtk_button_get_label (GTK_BUTTON(widget)); if(currentOption[data].type == SaveButton) GenericReadout(currentOption, -1); - snprintf(buf, MSG_SIZ, "option %s\n", name); - SendToProgram(buf, currentCps); - } else ((ButtonCallback*) currentOption[data].target)(data); + snprintf(buf, MSG_SIZ, "option %s\n", name); + SendToProgram(buf, currentCps); + } else ((ButtonCallback*) currentOption[data].target)(data); shells[dlg] = oldSh; // in case of multiple instances, restore previous (as this one could be popped down now) -#endif } +#ifdef TODO_GTK void TabProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) { // for transfering focus to the next text-edit -#ifdef TODO_GTK Option *opt; for(opt = currentOption; opt->type != EndMark; opt++) { if(opt->handle == w) { @@ -727,13 +890,13 @@ TabProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) } } } -#endif } +#endif +#ifdef TODO_GTK void WheelProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) { // for scrolling a widget seen through a viewport with the mouse wheel (ListBox!) -#ifdef TODO_GTK int j=0, n = atoi(prms[0]); static char *params[3] = { "", "Continuous", "Proportional" }; Arg args[16]; @@ -756,8 +919,8 @@ WheelProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) XtCallActionProc(v, "NotifyThumb", event, params, 0); // XtCallActionProc(w, "NotifyScroll", event, params+2, 1); XtCallActionProc(v, "EndScroll", event, params, 0); -#endif } +#endif static char *oneLiner = "Return: redraw-display() \n \ @@ -795,11 +958,11 @@ SqueezeIntoBox (Option *opt, int nr, int width) #endif } +#ifdef TODO_GTK int SetPositionAndSize (Arg *args, Widget leftNeigbor, Widget topNeigbor, int b, int w, int h, int chaining) { // sizing and positioning most widgets have in common int j = 0; -#ifdef TODO_GTK // first position the widget w.r.t. earlier ones if(chaining & 1) { // same row: position w.r.t. last (on current row) and lastrow XtSetArg(args[j], XtNfromVert, topNeigbor); j++; @@ -826,13 +989,393 @@ SetPositionAndSize (Arg *args, Widget leftNeigbor, Widget topNeigbor, int b, int if(b == 3) b = 1; // border XtSetArg(args[j], XtNborderWidth, b); j++; -#endif return j; } +#endif int -GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal, int top) -{ +GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent, int modal, int topLevel) +{ + GtkWidget *dialog = NULL; + gint w; + GtkWidget *label; + GtkWidget *box; + GtkWidget *checkbutton; + GtkWidget *entry; + GtkWidget *hbox; + GtkWidget *button; + GtkWidget *table; + GtkWidget *spinner; + GtkAdjustment *spinner_adj; + GtkWidget *combobox; + GtkWidget *textview; + GtkTextBuffer *textbuffer; + GdkColor color; + GtkWidget *actionarea; + GtkWidget *sw; + GtkWidget *list; + GtkWidget *graph; + GtkWidget *menuButton; + GtkWidget *menuBar; + GtkWidget *menu; + + 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) + gtk_widget_show(shells[dlgNr]); + shellUp[dlgNr] = True; + return 0; + } + + dialogOptions[dlgNr] = option; // make available to callback + // post currentOption globally, so Spin and Combo callbacks can already use it + // WARNING: this kludge does not work for persistent dialogs, so that these cannot have spin or combo controls! + currentOption = option; + + if(engineDlg) { // Settings popup for engine: format through heuristic + int n = currentCps->nrOptions; + if(n > 50) width = 4; else if(n>24) width = 2; else width = 1; + height = n / width + 1; +// if(n && (currentOption[n-1].type == Button || currentOption[n-1].type == SaveButton)) currentOption[n].min = SAME_ROW; // OK on same line + currentOption[n].type = EndMark; currentOption[n].target = NULL; // delimit list by callback-less end mark + } + +#ifdef TODO_GTK + i = 0; + XtSetArg(args[i], XtNresizable, True); i++; + shells[BoardWindow] = shellWidget; parents[dlgNr] = parent; + + if(dlgNr == BoardWindow) dialog = shellWidget; else + dialog = + XtCreatePopupShell(title, !top || !appData.topLevel ? transientShellWidgetClass : topLevelShellWidgetClass, + shells[parent], args, i); +#endif + dialog = gtk_dialog_new_with_buttons( title, + NULL, + GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR | + (modal ? GTK_DIALOG_MODAL : 0), + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + NULL ); + + shells[dlgNr] = dialog; + box = gtk_dialog_get_content_area( GTK_DIALOG( dialog ) ); + gtk_box_set_spacing(GTK_BOX(box), 5); + + arraysize = 0; + for (i=0;option[i].type != EndMark;i++) { + arraysize++; + } + + table = gtk_table_new(arraysize, 3, FALSE); + gtk_table_set_col_spacings(GTK_TABLE(table), 20); + left = 0; + top = -1; + + for (i=0;option[i].type != EndMark;i++) { + if(option[i].type == -1) continue; + top++; + if (top >= height) { + top = 0; + left = left + 3; + gtk_table_resize(GTK_TABLE(table), height, left + 3); + } + switch(option[i].type) { + case Fractional: + snprintf(def, MSG_SIZ, "%.2f", *(float*)option[i].target); + option[i].value = *(float*)option[i].target; + goto tBox; + case Spin: + if(!currentCps) option[i].value = *(int*)option[i].target; + snprintf(def, MSG_SIZ, "%d", option[i].value); + case TextBox: + case FileName: + case PathName: + tBox: + label = gtk_label_new(option[i].name); + /* Left Justify */ + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + + /* width */ + w = option[i].type == Spin || option[i].type == Fractional ? 70 : option[i].max ? option[i].max : 205; + if(option[i].type == FileName || option[i].type == PathName) w -= 55; + + if (option[i].type==TextBox && option[i].min > 80){ + textview = gtk_text_view_new(); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD); + /* add textview to scrolled window so we have vertical scroll bar */ + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_container_add(GTK_CONTAINER(sw), textview); + gtk_widget_set_size_request(GTK_WIDGET(sw), w, -1); + + textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); + gtk_widget_set_size_request(textview, -1, option[i].min); + /* check if label is empty */ + if (strcmp(option[i].name,"") != 0) { + gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+1, top, top+1); + gtk_table_attach_defaults(GTK_TABLE(table), sw, left+1, left+3, top, top+1); + } + else { + /* no label so let textview occupy all columns */ + gtk_table_attach_defaults(GTK_TABLE(table), sw, left, left+3, top, top+1); + } + if ( *(char**)option[i].target != NULL ) + gtk_text_buffer_set_text (textbuffer, *(char**)option[i].target, -1); + else + gtk_text_buffer_set_text (textbuffer, "", -1); + option[i].handle = (void*)textbuffer; + break; + } + + entry = gtk_entry_new(); + + if (option[i].type==Spin || option[i].type==Fractional) + gtk_entry_set_text (GTK_ENTRY (entry), def); + else if (currentCps) + gtk_entry_set_text (GTK_ENTRY (entry), option[i].textValue); + else if ( *(char**)option[i].target != NULL ) + gtk_entry_set_text (GTK_ENTRY (entry), *(char**)option[i].target); + + //gtk_entry_set_width_chars (GTK_ENTRY (entry), 18); + gtk_entry_set_max_length (GTK_ENTRY (entry), w); + + // left, right, top, bottom + if (strcmp(option[i].name, "") != 0) gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+1, top, top+1); + //gtk_table_attach_defaults(GTK_TABLE(table), entry, 1, 2, i, i+1); + + if (option[i].type == Spin) { + spinner_adj = (GtkAdjustment *) gtk_adjustment_new (option[i].value, option[i].min, option[i].max, 1.0, 0.0, 0.0); + spinner = gtk_spin_button_new (spinner_adj, 1.0, 0); + gtk_table_attach_defaults(GTK_TABLE(table), spinner, left+1, left+3, top, top+1); + option[i].handle = (void*)spinner; + } + else if (option[i].type == FileName || option[i].type == PathName) { + gtk_table_attach_defaults(GTK_TABLE(table), entry, left+1, left+2, top, top+1); + button = gtk_button_new_with_label ("Browse"); + gtk_table_attach_defaults(GTK_TABLE(table), button, left+2, left+3, top, top+1); + g_signal_connect (button, "clicked", G_CALLBACK (Browse), (gpointer)(intptr_t) i); + option[i].handle = (void*)entry; + } + else { + hbox = gtk_hbox_new (FALSE, 0); + if (strcmp(option[i].name, "") == 0) + gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+3, top, top+1); + else + gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1); + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0); + //gtk_table_attach_defaults(GTK_TABLE(table), entry, left+1, left+3, top, top+1); + option[i].handle = (void*)entry; + } + break; + case CheckBox: + checkbutton = gtk_check_button_new_with_label(option[i].name); + if(!currentCps) option[i].value = *(Boolean*)option[i].target; + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton), option[i].value); + gtk_table_attach_defaults(GTK_TABLE(table), checkbutton, left, left+3, top, top+1); + option[i].handle = (void *)checkbutton; + break; + case Label: + label = gtk_label_new(option[i].name); + /* Left Justify */ + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+3, top, top+1); + break; + case SaveButton: + case Button: + button = gtk_button_new_with_label (option[i].name); + + /* set button color on view board dialog */ + if(option[i].choice && ((char*)option[i].choice)[0] == '#' && !currentCps) { + gdk_color_parse( *(char**) option[i-1].target, &color ); + gtk_widget_modify_bg ( GTK_WIDGET(button), GTK_STATE_NORMAL, &color ); + } + + /* set button color on new variant dialog */ + if(option[i].textValue) { + gdk_color_parse( option[i].textValue, &color ); + gtk_widget_modify_bg ( GTK_WIDGET(button), GTK_STATE_NORMAL, &color ); + gtk_widget_set_sensitive(button, appData.noChessProgram || option[i].value < 0 + || strstr(first.variants, VariantName(option[i].value))); + } + + if (!(option[i].min & 1)) { + if(option[i].textValue) // for new variant dialog give buttons equal space so they line up nicely + hbox = gtk_hbox_new (TRUE, 0); + else + hbox = gtk_hbox_new (FALSE, 0); + // if only 1 button then put it in 1st column of table only + if ( (arraysize >= (i+1)) && option[i+1].type != Button ) + gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+1, top, top+1); + else + gtk_table_attach_defaults(GTK_TABLE(table), hbox, left, left+3, top, top+1); + } + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + g_signal_connect (button, "clicked", G_CALLBACK (GenericCallback), (gpointer)(intptr_t) i + (dlgNr<<16)); + option[i].handle = (void*)button; + break; + case ComboBox: + label = gtk_label_new(option[i].name); + /* Left Justify */ + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_table_attach_defaults(GTK_TABLE(table), label, left, left+1, top, top+1); + + combobox = gtk_combo_box_new_text(); + + for(j=0;;j++) { + if ( ((char **) option[i].textValue)[j] == NULL) break; + gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), ((char **) option[i].textValue)[j]); + } + + if(currentCps) + option[i].choice = (char**) option[i].textValue; + else { + for(j=0; option[i].choice[j]; j++) { + if(*(char**)option[i].target && !strcmp(*(char**)option[i].target, option[i].choice[j])) break; + } + /* If choice is NULL set to first */ + if (option[i].choice[j] == NULL) + option[i].value = 0; + else + option[i].value = j; + } + + //option[i].value = j + (option[i].choice[j] == NULL); + gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), option[i].value); + + + hbox = gtk_hbox_new (FALSE, 0); + gtk_table_attach_defaults(GTK_TABLE(table), hbox, left+1, left+3, top, top+1); + gtk_box_pack_start (GTK_BOX (hbox), combobox, TRUE, TRUE, 0); + //gtk_table_attach_defaults(GTK_TABLE(table), combobox, 1, 2, i, i+1); + + g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(ComboSelect), (gpointer) (intptr_t) (i + 256*dlgNr)); + + option[i].handle = (void*)combobox; + values[i] = option[i].value; + break; + case ListBox: + { + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + GtkListStore *store; + + option[i].handle = (void *) (list = gtk_tree_view_new()); + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("List Items", renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(list), column); + store = gtk_list_store_new(1, G_TYPE_STRING); // 1 column of text + gtk_tree_view_set_model(GTK_TREE_VIEW(list), GTK_TREE_MODEL(store)); + g_object_unref(store); + LoadListBox(&option[i], "?", -1, -1); + HighlightListBoxItem(&option[i], 0); + + /* add listbox to scrolled window so we have vertical scroll bar */ + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(sw), list); + gtk_widget_set_size_request(GTK_WIDGET(sw), w, 300); + + /* never has label, so let listbox occupy all columns */ + gtk_table_attach_defaults(GTK_TABLE(table), sw, left, left+3, top, top+1); + } + break; + case Graph: + option[i].handle = (void*) (graph = gtk_drawing_area_new()); + gtk_widget_set_size_request(graph, option[i].max, option[i].value); + gtk_table_attach_defaults(GTK_TABLE(table), graph, left, left+3, top, top+1); + +#ifdef TODO_GTK + XtAddEventHandler(last, ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, False, + (XtEventHandler) GraphEventProc, &option[i]); // mandatory user-supplied expose handler + if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow; +#endif + option[i].choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, option[i].max, option[i].value); // image buffer + break; +#ifdef TODO_GTK + case Graph: + j = SetPositionAndSize(args, last, lastrow, 0 /* border */, + option[i].max /* w */, option[i].value /* h */, option[i].min /* chain */); + option[i].handle = (void*) + (last = XtCreateManagedWidget("graph", widgetClass, form, args, j)); + XtAddEventHandler(last, ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask, False, + (XtEventHandler) GraphEventProc, &option[i]); // mandatory user-supplied expose handler + if(option[i].min & SAME_ROW) last = forelast, forelast = lastrow; + option[i].choice = (char**) cairo_image_surface_create (CAIRO_FORMAT_ARGB32, option[i].max, option[i].value); // image buffer + break; + case PopUp: // note: used only after Graph, so 'last' refers to the Graph widget + option[i].handle = (void*) CreateComboPopup(last, option + i, i + 256*dlgNr, TRUE, option[i].value); + break; + case BoxBegin: + if(option[i].min & SAME_ROW) forelast = lastrow; + j = SetPositionAndSize(args, last, lastrow, 0 /* border */, + 0 /* w */, 0 /* h */, option[i].min /* chain */); + XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++; + XtSetArg(args[j], XtNvSpace, 0); j++; + option[box=i].handle = (void*) + (last = XtCreateWidget("box", boxWidgetClass, form, args, j)); + oldForm = form; form = last; oldLastRow = lastrow; oldForeLast = forelast; + lastrow = NULL; last = NULL; + break; +#endif + case DropDown: + msg = _(option[i].name); // write name on the menu button +// XtSetArg(args[j], XtNmenuName, XtNewString(option[i].name)); j++; +// XtSetArg(args[j], XtNlabel, msg); j++; + option[i].handle = (void*) + (menuButton = gtk_menu_item_new_with_label(msg)); + gtk_widget_show(menuButton); + option[i].textValue = (char*) (menu = CreateMenuPopup(option + i, i + 256*dlgNr, -1)); + gtk_menu_item_set_submenu(GTK_MENU_ITEM (menuButton), menu); + gtk_menu_bar_append (GTK_MENU_BAR (menuBar), menuButton); + + break; + case BarBegin: + menuBar = gtk_menu_bar_new (); + gtk_widget_show (menuBar); + case BoxBegin: + boxStart = i; + break; + case BarEnd: + gtk_table_attach_defaults(GTK_TABLE(table), menuBar, left, left+1, top, top+1); + case BoxEnd: +// XtManageChildren(&form, 1); +// SqueezeIntoBox(&option[boxStart], i-boxStart, option[boxStart].max); + if(option[i].target) ((ButtonCallback*)option[i].target)(boxStart); // callback that can make sizing decisions + break; + case Break: + top = height; // force next option to start in a new column + break; + default: + printf("GenericPopUp: unexpected case in switch. i=%d type=%d name=%s.\n", i, option[i].type, option[i].name); + break; + } + } + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + table, TRUE, TRUE, 0); + + /* Show dialog */ + gtk_widget_show_all( dialog ); + + /* hide OK/cancel buttons */ + if((option[i].min & 2)) { + actionarea = gtk_dialog_get_action_area(GTK_DIALOG(dialog)); + gtk_widget_hide(actionarea); + } + + g_signal_connect (dialog, "response", + G_CALLBACK (GenericPopUpCallback), + (gpointer)(intptr_t) (dlgNr<<16 | i)); + g_signal_connect (dialog, "delete-event", + G_CALLBACK (GenericPopDown), + (gpointer)(intptr_t) dlgNr); + shellUp[dlgNr]++; + #ifdef TODO_GTK Arg args[24]; Widget popup, layout, dialog=NULL, edit=NULL, form, last, b_ok, b_cancel, previousPane = NULL, textField = NULL, oldForm, oldLastRow, oldForeLast; @@ -1232,7 +1775,6 @@ GenericPopUp (Option *option, char *title, DialogClass dlgNr, DialogClass parent return 1; // tells caller he must do initialization (e.g. add specific event handlers) } - /* function called when the data to Paste is ready */ #ifdef TODO_GTK static void diff --git a/xtimer.c b/xtimer.c index 46dd334..96313f9 100644 --- a/xtimer.c +++ b/xtimer.c @@ -57,6 +57,8 @@ #include #include +#include + #if STDC_HEADERS # include # include @@ -92,17 +94,9 @@ extern char *getenv(); # include #endif -#include - -// [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are. #include "common.h" -#include "frontend.h" #include "backend.h" -#include "backendz.h" -#include "moves.h" -#include "xboard.h" -#include "xboard2.h" - +#include "frontend.h" #ifdef __EMX__ #ifndef HAVE_USLEEP @@ -111,35 +105,32 @@ extern char *getenv(); #define usleep(t) _sleep2(((t)+500)/1000) #endif -// in xboard.c (should go to xtimer.h ?) -extern XtAppContext appContext; - -XtIntervalId delayedEventTimerXID = 0; +guint delayedEventTimerTag = 0; DelayedEventCallback delayedEventCallback = 0; void -FireDelayedEvent () +FireDelayedEvent(gpointer data) { - delayedEventTimerXID = 0; + g_source_remove(delayedEventTimerTag); + delayedEventTimerTag = 0; delayedEventCallback(); } void ScheduleDelayedEvent (DelayedEventCallback cb, long millisec) { - if(delayedEventTimerXID && delayedEventCallback == cb) + if(delayedEventTimerTag && delayedEventCallback == cb) // [HGM] alive: replace, rather than add or flush identical event - XtRemoveTimeOut(delayedEventTimerXID); + g_source_remove(delayedEventTimerTag); + delayedEventCallback = cb; delayedEventCallback = cb; - delayedEventTimerXID = - XtAppAddTimeOut(appContext, millisec, - (XtTimerCallbackProc) FireDelayedEvent, (XtPointer) 0); + delayedEventTimerTag = g_timeout_add(millisec,(GSourceFunc) FireDelayedEvent, NULL); } DelayedEventCallback GetDelayedEvent () { - if (delayedEventTimerXID) { + if (delayedEventTimerTag) { return delayedEventCallback; } else { return NULL; @@ -149,26 +140,26 @@ GetDelayedEvent () void CancelDelayedEvent () { - if (delayedEventTimerXID) { - XtRemoveTimeOut(delayedEventTimerXID); - delayedEventTimerXID = 0; + if (delayedEventTimerTag) { + g_source_remove(delayedEventTimerTag); + delayedEventTimerTag = 0; } } -XtIntervalId loadGameTimerXID = 0; -int -LoadGameTimerRunning () +guint loadGameTimerTag = 0; + +int LoadGameTimerRunning() { - return loadGameTimerXID != 0; + return loadGameTimerTag != 0; } int StopLoadGameTimer () { - if (loadGameTimerXID != 0) { - XtRemoveTimeOut(loadGameTimerXID); - loadGameTimerXID = 0; + if (loadGameTimerTag != 0) { + g_source_remove(loadGameTimerTag); + loadGameTimerTag = 0; return TRUE; } else { return FALSE; @@ -176,56 +167,53 @@ StopLoadGameTimer () } void -LoadGameTimerCallback (XtPointer arg, XtIntervalId *id) +LoadGameTimerCallback(gpointer data) { - loadGameTimerXID = 0; + g_source_remove(loadGameTimerTag); + loadGameTimerTag = 0; AutoPlayGameLoop(); } void StartLoadGameTimer (long millisec) { - loadGameTimerXID = - XtAppAddTimeOut(appContext, millisec, - (XtTimerCallbackProc) LoadGameTimerCallback, - (XtPointer) 0); + loadGameTimerTag = + g_timeout_add( millisec, (GSourceFunc) LoadGameTimerCallback, NULL); } -XtIntervalId analysisClockXID = 0; +guint analysisClockTag = 0; void -AnalysisClockCallback (XtPointer arg, XtIntervalId *id) +AnalysisClockCallback(gpointer data) { if (gameMode == AnalyzeMode || gameMode == AnalyzeFile || appData.icsEngineAnalyze) { // [DM] AnalysisPeriodicEvent(0); - StartAnalysisClock(); } } void StartAnalysisClock () { - analysisClockXID = - XtAppAddTimeOut(appContext, 2000, - (XtTimerCallbackProc) AnalysisClockCallback, - (XtPointer) 0); + analysisClockTag = + g_timeout_add( 2000,(GSourceFunc) AnalysisClockCallback, NULL); } -XtIntervalId clockTimerXID = 0; +guint clockTimerTag = 0; int ClockTimerRunning () { - return clockTimerXID != 0; + return clockTimerTag != 0; } int StopClockTimer () { - if (clockTimerXID != 0) { - XtRemoveTimeOut(clockTimerXID); - clockTimerXID = 0; + if (clockTimerTag != 0) + { + g_source_remove(clockTimerTag); + clockTimerTag = 0; return TRUE; } else { return FALSE; @@ -233,19 +221,19 @@ StopClockTimer () } void -ClockTimerCallback (XtPointer arg, XtIntervalId *id) +ClockTimerCallback(gpointer data) { - clockTimerXID = 0; + /* remove timer */ + g_source_remove(clockTimerTag); + clockTimerTag = 0; + DecrementClocks(); } void StartClockTimer (long millisec) { - clockTimerXID = - XtAppAddTimeOut(appContext, millisec, - (XtTimerCallbackProc) ClockTimerCallback, - (XtPointer) 0); + clockTimerTag = g_timeout_add(millisec,(GSourceFunc) ClockTimerCallback,NULL); } -- 1.7.0.4