Updated copyright notice to 2015
[xboard.git] / gtk / xboard.c
index 81fc8d6..5da2d3e 100644 (file)
@@ -5,7 +5,7 @@
  * 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 Free Software Foundation, Inc.
  *
  * The following terms apply to Digital Equipment Corporation's copyright
  * interest in XBoard:
@@ -167,8 +167,8 @@ extern char *getenv();
 #include "gettext.h"
 #include "draw.h"
 
-#ifdef __APPLE__
-#  include <gtkmacintegration/gtkosxapplication.h>
+#ifdef OSXAPP
+#  include <gtkmacintegration-gtk2/gtkosxapplication.h>
    // prevent pathname of positional file argument provided by OS X being be mistaken for option name
    // (price is that we won't recognize Windows option format anymore).
 #  define SLASH '-'
@@ -650,9 +650,12 @@ ResizeBoardWindow (int w, int h, int inhibit)
     gtk_widget_get_allocation(shellWidget, &a);
     marginW = a.width - bw;
     gtk_widget_get_allocation(optList[W_WHITE].handle, &a);
-    w += marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed...
-    h += marginH + a.height + 1;
+    gtk_widget_set_size_request(optList[W_BOARD].handle, w, h);   // protect board widget
+//    w += marginW + 1; // [HGM] not sure why the +1 is (sometimes) needed...
+//    h += marginH + a.height + 1;
     gtk_window_resize(GTK_WINDOW(shellWidget), w, h);
+    DoEvents();
+    gtk_widget_set_size_request(optList[W_BOARD].handle, -1, -1); // liberate board again
 }
 
 int
@@ -828,7 +831,7 @@ LoadIconFile (gchar *svgFilename)
     return gdk_pixbuf_new_from_file(buf, NULL);
 }
 
-#ifdef __APPLE__
+#ifdef OSXAPP
 static char clickedFile[MSG_SIZ];
 static int suppress;
 
@@ -874,7 +877,7 @@ main (int argc, char **argv)
 
     /* set up GTK */
     gtk_init (&argc, &argv);
-#ifdef __APPLE__
+#ifdef OSXAPP
     {   // prepare to catch OX OpenFile signal, which will tell us the clicked file
        char *path = gtkosx_application_get_bundle_path();
 #ifdef ENABLE_NLS
@@ -882,11 +885,12 @@ main (int argc, char **argv)
        snprintf(localeDir, MSG_SIZ, "%s/share/locale", res_path); // redefine locale dir for OSX bundle
 #endif
        theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
-       strncpy(dataDir, path, MSG_SIZ);
        snprintf(masterSettings, MSG_SIZ, "%s/Contents/Resources/etc/xboard.conf", path);
-       snprintf(svgDir, MSG_SIZ, "%s/Contents/Resources/share/xboard/themes/default", 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);
+       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()));
@@ -1193,7 +1197,7 @@ 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
+       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
     }
 
@@ -1652,26 +1656,34 @@ void
 ReSize (WindowPlacement *wp)
 {
        GtkAllocation a;
-       int sqx, sqy, w, h, hc, lg = lineGap;
-       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;
+       int sqx, sqy, w, h, lg = lineGap;
+       static int first = 1;
+       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
        }
-       if(sqx != squareSize) {
+       if(sqx != squareSize && !first) {
            squareSize = sqx; // adopt new square size
            CreatePNGPieces(); // make newly scaled pieces
            InitDrawingSizes(0, 0); // creates grid etc.
@@ -1680,6 +1692,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 = appData.fixedSize;
 }
 
 static guint delayedDragTag = 0;
@@ -1691,7 +1704,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
@@ -1917,7 +1930,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);
 }
 
@@ -1951,9 +1964,9 @@ TempForwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms)
 void
 ManProc ()
 {   // called from menu
-#ifdef __APPLE__
+#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 &");
@@ -1961,6 +1974,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
@@ -2064,7 +2091,7 @@ SetClockIcon (int color)
     GdkPixbuf *pm = *clockIcons[color];
     if (mainwindowIcon != pm) {
         mainwindowIcon = pm;
-#ifdef __APPLE__
+#ifdef OSXAPP
         gtkosx_application_set_dock_icon_pixbuf(theApp, mainwindowIcon);
 #else
         gtk_window_set_icon(GTK_WINDOW(shellWidget), mainwindowIcon);
@@ -2304,6 +2331,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);
@@ -2377,12 +2413,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;