X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=gtk%2Fxboard.c;h=de5da1228b34bf7ecfa96d726621bc605623273a;hb=ebd7f78161504e46896f7d96bb41e29714b2fd53;hp=e2a3237643142a7b5aa2da81cca53ef652d6529a;hpb=c62291ec96fd3fb40ff7cd6b34a0d3ec830b20e4;p=xboard.git diff --git a/gtk/xboard.c b/gtk/xboard.c index e2a3237..de5da12 100644 --- a/gtk/xboard.c +++ b/gtk/xboard.c @@ -5,7 +5,8 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free + * Software Foundation, Inc. * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -62,7 +63,6 @@ #include #include #include -#include #include #if !OMIT_SOCKETS @@ -212,11 +212,13 @@ RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); RETSIGTYPE TermSizeSigHandler P((int sig)); char *InsertPxlSize P((char *pattern, int targetPxlSize)); +#ifdef TODO_GTK #if ENABLE_NLS XFontSet CreateFontSet P((char *base_fnt_lst)); #else char *FindFont P((char *pattern, int targetPxlSize)); #endif +#endif void DelayedDrag P((void)); void ICSInputBoxPopUp P((void)); void MoveTypeInProc P((GdkEventKey *eventkey)); @@ -833,19 +835,21 @@ LoadIconFile (gchar *svgFilename) #ifdef OSXAPP static char clickedFile[MSG_SIZ]; -static int suppress; +TimeMark started; static gboolean StartNewXBoard(GtkosxApplication *app, gchar *path, gpointer user_data) { // handler of OSX OpenFile signal, which sends us the filename of clicked file or first argument - if(suppress) { // we just started XBoard without arguments - strncpy(clickedFile, path, MSG_SIZ); // remember file name, but otherwise ignore - } else { // we are running something presumably useful - char buf[MSG_SIZ]; - snprintf(buf, MSG_SIZ, "open -n -a \"xboard\" --args \"%s\"", path); - system(buf); // start new instance on this file - } - return TRUE; + TimeMark now; + GetTimeMark(&now); + if(1000*now.sec + now.ms - 1000*started.sec - started.ms < 1000) { // received during first second + strncpy(clickedFile, path, MSG_SIZ); // remember file name, but otherwise ignore + } else { // we are running something presumably useful + char buf[MSG_SIZ]; + snprintf(buf, MSG_SIZ, "open -n -a \"xboard\" --args \"%s\"", path); + system(buf); // start new instance on this file + } + return TRUE; } GtkosxApplication *theApp; @@ -879,32 +883,32 @@ main (int argc, char **argv) gtk_init (&argc, &argv); #ifdef OSXAPP { // prepare to catch OX OpenFile signal, which will tell us the clicked file - char *path = gtkosx_application_get_bundle_path(); + char *path = gtkosx_application_get_bundle_path(); #ifdef ENABLE_NLS - char *res_path = gtkosx_application_get_resource_path(); - snprintf(localeDir, MSG_SIZ, "%s/share/locale", res_path); // redefine locale dir for OSX bundle + char *res_path = gtkosx_application_get_resource_path(); + snprintf(localeDir, MSG_SIZ, "%s/share/locale", res_path); // redefine locale dir for OSX bundle #endif - theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL); - snprintf(masterSettings, MSG_SIZ, "%s/Contents/Resources/etc/xboard.conf", path); - snprintf(dataDir, MSG_SIZ, "%s/Contents/Resources/share/xboard", path); - snprintf(svgDir, MSG_SIZ, "%s/themes/default", dataDir); - suppress = (argc == 1 || argc > 1 && argv[1][00] != '-'); // OSX sends signal even if name was already argv[1]! - g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(StartNewXBoard), NULL); - // we must call application ready before we can get the signal, - // and supply a (dummy) menu bar before that, to avoid problems with dual apples in it - gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(gtk_menu_bar_new())); - gtkosx_application_ready(theApp); - if(argc == 1) { // called without args: OSX open-file signal might follow - static char *fakeArgv[3] = {NULL, clickedFile, NULL}; - usleep(10000); // wait 10 msec (and hope this is long enough). - while(gtk_events_pending()) - gtk_main_iteration(); // process all events that came in upto now - suppress = 0; // future open-file signals should start new instance - if(clickedFile[0]) { // we were sent an open-file signal with filename! - fakeArgv[0] = argv[0]; - argc = 2; argv = fakeArgv; // fake that we were called as "xboard filename" - } - } + GetTimeMark(&started); // remember start time + theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL); + snprintf(masterSettings, MSG_SIZ, "%s/Contents/Resources/etc/xboard.conf", path); + snprintf(dataDir, MSG_SIZ, "%s/Contents/Resources/share/xboard", path); + snprintf(svgDir, MSG_SIZ, "%s/themes/default", dataDir); + g_signal_connect(theApp, "NSApplicationOpenFile", G_CALLBACK(StartNewXBoard), NULL); + g_signal_connect(theApp, "NSApplicationWillTerminate", G_CALLBACK(ExitEvent), NULL); + // we must call application ready before we can get the signal, + // and supply a (dummy) menu bar before that, to avoid problems with dual apples in it + gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(gtk_menu_bar_new())); + gtkosx_application_ready(theApp); + if(argc == 1) { // called without args: OSX open-file signal might follow + static char *fakeArgv[3] = {NULL, clickedFile, NULL}; + usleep(10000); // wait 10 msec (and hope this is long enough). + while(gtk_events_pending()) + gtk_main_iteration(); // process all events that came in upto now + if(clickedFile[0]) { // we were sent an open-file signal with filename! + fakeArgv[0] = argv[0]; + argc = 2; argv = fakeArgv; // fake that we were called as "xboard filename" + } + } } #endif @@ -1019,8 +1023,6 @@ main (int argc, char **argv) programName, appData.boardSize); exit(2); } - if(BOARD_WIDTH > 8) - squareSize = (squareSize*8 + BOARD_WIDTH/2)/BOARD_WIDTH; // scale height if (i < 7) { /* Find some defaults; use the nearest known size */ SizeDefaults *szd, *nearest; @@ -1072,6 +1074,10 @@ main (int argc, char **argv) tinyLayout = szd->tinyLayout; // [HGM] font: use defaults from settings file if available and not overruled } + if(BOARD_WIDTH != 8) { + squareSize = (squareSize*8 + BOARD_WIDTH/2)/BOARD_WIDTH; // keep width the same + lineGap = (squareSize < 37 ? 1 : squareSize < 59 ? 2 : squareSize < 116 ? 3 : 4); + } defaultLineGap = lineGap; if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; @@ -1196,8 +1202,8 @@ main (int argc, char **argv) gtk_widget_get_allocation(optList[W_WHITE].handle, &a); clockKludge = hc = a.height; gtk_widget_get_allocation(boardWidget, &a); -// marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board -// marginH = h - a.height - hc; // subtract current clock height, so it can be added back dynamically + marginW = w - boardWidth; // [HGM] needed to set new shellWidget size when we resize board + marginH = h - a.height - hc; // subtract current clock height, so it can be added back dynamically } CreateAnyPieces(1); @@ -1655,22 +1661,29 @@ void ReSize (WindowPlacement *wp) { GtkAllocation a; - int sqx, sqy, w, h, hc, lg = lineGap; + int sqx, sqy, w, h, lg = lineGap; static int first = 1; - gtk_widget_get_allocation(optList[W_WHITE].handle, &a); - hc = a.height; // clock height can depend on single / double line clock text! -// if(clockKludge && hc != clockKludge) wp->height += hc - clockKludge, clockKludge = 0; - wpMain.height = BOARD_HEIGHT * (squareSize + lineGap) + lineGap + marginH + hc; - if(wp->width == wpMain.width && wp->height == wpMain.height) return; // not sized - sqx = (wp->width - lg - marginW) / BOARD_WIDTH - lg; - sqy = (wp->height - lg - marginH - hc) / BOARD_HEIGHT - lg; + if(wp->width == wpMain.width && wp->height == wpMain.height && !first) return; // not sized + gtk_widget_get_allocation(optList[W_DROP+1].handle, &a); // table that should contain everything + w = a.width; h = a.height; + gtk_widget_get_allocation(shellWidget, &a); + if(a.width < w || a.height < h) { // outer window smaller than dialog content? + w = a.width - w; h = a.height - h; // subtract matrgins, measured as table minus board dimensions + gtk_widget_get_allocation(optList[W_BOARD].handle, &a); + w += a.width; h += a.height; + } else { + gtk_widget_get_allocation(optList[W_BOARD].handle, &a); + w = a.width; h = a.height; + } + sqx = (w - lg) / BOARD_WIDTH - lg; + sqy = (h - lg) / BOARD_HEIGHT - lg; if(sqy < sqx) sqx = sqy; if(sqx < 20) return; if(appData.overrideLineGap < 0) { // do second iteration with adjusted lineGap int oldSqx = sqx; lg = lineGap = sqx < 37 ? 1 : sqx < 59 ? 2 : sqx < 116 ? 3 : 4; - sqx = (wp->width - lg - marginW) / BOARD_WIDTH - lg; - sqy = (wp->height - lg - marginH - hc) / BOARD_HEIGHT - lg; + sqx = (w - lg) / BOARD_WIDTH - lg; + sqy = (h - lg) / BOARD_HEIGHT - lg; if(sqy < sqx) sqx = sqy; lg = sqx < 37 ? 1 : sqx < 59 ? 2 : sqx < 116 ? 3 : 4; if(sqx == oldSqx + 1 && lg == lineGap + 1) sqx = oldSqx, squareSize = 0; // prevent oscillations, force resize by kludge @@ -1684,7 +1697,7 @@ ReSize (WindowPlacement *wp) h = BOARD_HEIGHT * (squareSize + lineGap) + lineGap; if(optList[W_BOARD].max > w) optList[W_BOARD].max = w; if(optList[W_BOARD].value > h) optList[W_BOARD].value = h; - first = 0; + first = appData.fixedSize; } static guint delayedDragTag = 0; @@ -1696,7 +1709,7 @@ DragProc () if(busy) return; busy = 1; -// GetActualPlacement(shellWidget, &wpNew); + GetActualPlacement(shellWidget, &wpNew); if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved wpNew.width == wpMain.width && wpNew.height == wpMain.height) { // not sized busy = 0; return; // false alarm @@ -1765,7 +1778,7 @@ void ModeHighlight () { static int oldPausing = FALSE; - static GameMode oldmode = (GameMode) -1; + static GameMode oldMode = (GameMode) -1; char *wname; if (!boardWidget) return; @@ -1783,7 +1796,7 @@ ModeHighlight () } } - wname = ModeToWidgetName(oldmode); + wname = ModeToWidgetName(oldMode); if (wname != NULL) { MarkMenuItem(wname, False); } @@ -1791,8 +1804,9 @@ ModeHighlight () if (wname != NULL) { MarkMenuItem(wname, True); } - oldmode = gameMode; + if(oldMode == TwoMachinesPlay) EnableNamedMenuItem("Mode.MachineMatch", True); MarkMenuItem("Mode.MachineMatch", matchMode && matchGame < appData.matchGames); + oldMode = gameMode; /* Maybe all the enables should be handled here, not just this one */ EnableNamedMenuItem("Mode.Training", gameMode == Training || gameMode == PlayFromGameFile); @@ -1922,7 +1936,7 @@ void MoveTypeInProc(eventkey) buf[0]=eventkey->keyval; buf[1]='\0'; - if (eventkey->keyval > 32 && eventkey->keyval < 256) + if (eventkey->keyval > 32 && eventkey->keyval < 256 || *buf == 27) ConsoleAutoPopUp (buf); } @@ -1958,7 +1972,7 @@ ManProc () { // called from menu #ifdef OSXAPP char buf[MSG_SIZ]; - snprintf(buf, MSG_SIZ, "%s ./man.command", appData.sysOpen); + snprintf(buf, MSG_SIZ, "osascript -e 'tell application \"Terminal\"' -e 'activate' -e 'do script \"man %s/../man/man6/xboard.6\"' -e 'end tell'", dataDir); system(buf); #else system("xterm -e man xboard &"); @@ -1966,6 +1980,20 @@ ManProc () } void +InfoProc () +{ + char buf[MSG_SIZ]; +#ifdef OSXAPP + snprintf(buf, MSG_SIZ, "osascript -e 'tell application \"Terminal\"' -e 'activate' -e 'do script \"info -d %s/../info -f xboard.info\"' -e 'end tell'", dataDir); +#else + snprintf(buf, sizeof(buf), "xterm -e info --directory %s --directory . -f %s &", + INFODIR, INFOFILE); +#endif + system(buf); +} + + +void SetWindowTitle (char *text, char *title, char *icon) { #ifdef TODO_GTK @@ -2309,6 +2337,15 @@ void FileNamePopUpWrapper(label, def, filter, proc, pathFlag, openMode, name, fp char fileext[10] = ""; char *result = NULL; char *cp; + char curDir[MSG_SIZ]; + + StartDir(filter, NULL); // change to start directory for this file type + + if(def && *def && def[strlen(def)-1] == '/') { + getcwd(curDir, MSG_SIZ); + chdir(def); + } + /* make a copy of the filter string, so that strtok can work with it*/ cp = strdup(filter); @@ -2382,12 +2419,16 @@ void FileNamePopUpWrapper(label, def, filter, proc, pathFlag, openMode, name, fp ASSIGN(*name, filename); ScheduleDelayedEvent(DelayedLoad, 50); } + StartDir(filter, filename); g_free (filename); - }; + } + else StartDir(filter, ""); gtk_widget_destroy (dialog); ModeHighlight(); + if(def && *def && def[strlen(def)-1] == '/') chdir(curDir); + free(cp); return;