Add UnloadEngine routine
[xboard.git] / xhistory.c
index 7f02ab8..fc5a88d 100644 (file)
@@ -1,29 +1,24 @@
 /*
  * xhistory.c -- Move list window, part of X front end for XBoard
- * $Id: xhistory.c,v 2.1 2003/10/27 19:21:00 mann Exp $
  *
- * Copyright 2000 Free Software Foundation, Inc.
- *
- * The following terms apply to the enhanced version of XBoard distributed
- * by the Free Software Foundation:
+ * Copyright 2000, 2009, 2010, 2011 Free Software Foundation, Inc.
  * ------------------------------------------------------------------------
- * This program is free software; you can redistribute it and/or modify
+ *
+ * GNU XBoard is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * GNU XBoard is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * ------------------------------------------------------------------------
+ * along with this program. If not, see http://www.gnu.org/licenses/.  *
  *
- * See the file ChangeLog for a revision history.
- */
+ *------------------------------------------------------------------------
+ ** See the file ChangeLog for a revision history.  */
 
 #include "config.h"
 
@@ -71,11 +66,20 @@ extern char *getenv();
 #include "backend.h"
 #include "xboard.h"
 #include "xhistory.h"
+#include "gettext.h"
+#include "xevalgraph.h"
 
+#ifdef ENABLE_NLS
+# define  _(s) gettext (s)
+# define N_(s) gettext_noop (s)
+#else
+# define  _(s) (s)
+# define N_(s)  s
+#endif
 
 #define _LL_ 100
 
-extern Widget formWidget, shellWidget, boardWidget, menuBarWidget;
+extern Widget formWidget, shellWidget, boardWidget, menuBarWidget, historyShell;
 extern Display *xDisplay;
 extern int squareSize;
 extern Pixmap xMarkPixmap;
@@ -83,13 +87,15 @@ extern char *layoutName;
 
 struct History{
   String *Nr,*white,*black;
-  int     aNr;  /* space actually alocated */  
+  int     aNr;  /* space actually alocated */
   Widget mvn,mvw,mvb,vbox,viewport,sh;
   char Up;
 };
 
 struct History *hist=0;
 String dots=" ... ";
+Position gameHistoryX, gameHistoryY;
+Dimension gameHistoryW, gameHistoryH;
 
 void
 HistoryPopDown(w, client_data, call_data)
@@ -98,14 +104,26 @@ HistoryPopDown(w, client_data, call_data)
 {
   Arg args[16];
   int j;
-  if(hist)
-
-  XtPopdown(hist->sh);
-  hist->Up=False;
+  if(hist) {
 
+    // [HGM] remember old position
+    j = 0;
+    XtSetArg(args[j], XtNx, &gameHistoryX);  j++;
+    XtSetArg(args[j], XtNy, &gameHistoryY);  j++;
+    XtSetArg(args[j], XtNwidth, &gameHistoryW);  j++;
+    XtSetArg(args[j], XtNheight, &gameHistoryH);  j++;
+    XtGetValues(hist->sh, args, j);
+    wpMoveHistory.x = gameHistoryX - 4;
+    wpMoveHistory.y = gameHistoryY - 23;
+    wpMoveHistory.width  = gameHistoryW;
+    wpMoveHistory.height = gameHistoryH;
+
+    XtPopdown(hist->sh);
+    hist->Up=False;
+  }
   j=0;
   XtSetArg(args[j], XtNleftBitmap, None); j++;
-  XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move List"),
+  XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Move History"),
                args, j);
 }
 
@@ -130,20 +148,20 @@ void HistoryAlloc(int len){
     free(hist->Nr);free(hist->white);free(hist->black);
   }
   else{
-    hist=(struct History*)malloc(sizeof(struct History)); 
+    hist=(struct History*)malloc(sizeof(struct History));
   }
     hist->aNr=len;
     hist->Nr=(String*)malloc(hist->aNr*sizeof(String*));
     hist->white=(String*)malloc(hist->aNr*sizeof(String*));
     hist->black=(String*)malloc(hist->aNr*sizeof(String*));
-    
+
     hist->Nr[0]=(String)malloc(hist->aNr*6);
     hist->white[0]=(String)malloc(hist->aNr*MOVE_LEN);
     hist->black[0]=(String)malloc(hist->aNr*MOVE_LEN);
 
       sprintf(hist->Nr[0],"    ");
-      sprintf(hist->white[0],"White ");
-      sprintf(hist->black[0],"Black ");
+      sprintf(hist->white[0],_("White "));
+      sprintf(hist->black[0],_("Black "));
     for(i=1;i<hist->aNr;i++){
       hist->Nr[i]= hist->Nr[i-1]+6;
       hist->white[i]= hist->white[i-1]+MOVE_LEN;
@@ -155,7 +173,6 @@ void HistoryAlloc(int len){
 }
 
 
-#if 1
 /* Find empty space inside vbox form widget and redistribute it amongst
    the list widgets inside it. */
 /* This version sort of works */
@@ -187,7 +204,7 @@ HistoryFill()
   } else {
     extra = extra/2;
   }
+
   j = 0;
   XtSetArg(args[j], XtNwidth, &w);  j++;
   XtGetValues(hist->mvw, args, j);
@@ -204,75 +221,24 @@ HistoryFill()
   XtSetArg(args[j], XtNwidth, w);  j++;
   XtSetValues(hist->mvb, args, j);
 }
-#else
-/* Find empty space inside vbox form widget and redistribute it amongst
-   the list widgets inside it. */
-/* This version doesn't work */
-void
-HistoryFill()
-{
-  Arg args[16];
-  Dimension fw, niw, wiw, biw, nbw, wbw, bbw;
-  int j, nl, wl, bl, fdd;
-  long extra;
-
-  j = 0;
-  XtSetArg(args[j], XtNwidth, &fw);  j++;
-  XtSetArg(args[j], XtNdefaultDistance, &fdd);  j++;
-  XtGetValues(hist->vbox, args, j);
-
-  j = 0;
-  XtSetArg(args[j], XtNlongest, &nl);  j++;
-  XtSetArg(args[j], XtNinternalWidth, &niw);  j++;
-  XtSetArg(args[j], XtNborderWidth, &nbw);  j++;
-  XtGetValues(hist->mvn, args, j);
-
-  j = 0;
-  XtSetArg(args[j], XtNlongest, &wl);  j++;
-  XtSetArg(args[j], XtNinternalWidth, &wiw);  j++;
-  XtSetArg(args[j], XtNborderWidth, &wbw);  j++;
-  XtGetValues(hist->mvw, args, j);
-
-  j = 0;
-  XtSetArg(args[j], XtNlongest, &bl);  j++;
-  XtSetArg(args[j], XtNinternalWidth, &biw);  j++;
-  XtSetArg(args[j], XtNborderWidth, &bbw);  j++;
-  XtGetValues(hist->mvb, args, j);
-
-  extra = fw - 4*fdd -
-    nl - 1 - 2*niw - 2*nbw - wl - 2*wiw - 2*wbw - bl - 2*biw - 2*bbw;
-  if (extra < 0) extra = 0;
-
-  j = 0;
-  XtSetArg(args[j], XtNwidth, nl + 1 + 2*niw);  j++;
-  XtSetValues(hist->mvn, args, j);
-
-  j = 0;
-  XtSetArg(args[j], XtNwidth, wl + 2*wiw + extra/2);  j++;
-  XtSetValues(hist->mvw, args, j);
-
-  j = 0;
-  XtSetArg(args[j], XtNwidth, bl + 2*biw + extra/2);  j++;
-  XtSetValues(hist->mvb, args, j);
-}
-#endif
 
 void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
   int i,b,m;
+  Widget scroll;
   if(hist){
     if(last >= hist->aNr) HistoryAlloc(last+_LL_);
     for(i=0;i<last;i++) {
-      if((i%2)==0) { 
+      if((i%2)==0) {
        if(movelist[i][0]) {
          char* p = strchr(movelist[i], ' ');
          if (p) {
            strncpy(hist->white[i/2+1], movelist[i], p-movelist[i]);
            hist->white[i/2+1][p-movelist[i]] = NULLCHAR;
          } else {
-           strcpy(hist->white[i/2+1],movelist[i]);
-         }         
+           safeStrCpy(hist->white[i/2+1],movelist[i], MOVE_LEN);
+         }
        } else {
-         strcpy(hist->white[i/2+1],dots);
+         safeStrCpy(hist->white[i/2+1],dots, MOVE_LEN);
        }
       } else {
        if(movelist[i][0]) {
@@ -281,14 +247,14 @@ void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
            strncpy(hist->black[i/2+1], movelist[i], p-movelist[i]);
            hist->black[i/2+1][p-movelist[i]] = NULLCHAR;
          } else {
-           strcpy(hist->black[i/2+1],movelist[i]);
-         }         
+           safeStrCpy(hist->black[i/2+1],movelist[i], MOVE_LEN);
+         }
        } else {
-         strcpy(hist->black[i/2+1],"");
+         safeStrCpy(hist->black[i/2+1],"", MOVE_LEN);
        }
       }
     }
-    strcpy(hist->black[last/2+1],"");
+    safeStrCpy(hist->black[last/2+1],"", MOVE_LEN);
     b=first/2;
     m=(last+3)/2-b;
     XawFormDoLayout(hist->vbox, False);
@@ -310,7 +276,15 @@ void HistorySet(char movelist[][2*MOVE_LEN],int first,int last,int current){
       if(current) XawListHighlight(hist->mvb, current/2+1);
       else XawListUnhighlight(hist->mvb);
     }
+    if(scroll = XtNameToWidget(hist->sh, "*form.viewport.vertical")) { // [HGM] always scroll to bottom
+      static char *params[3] = { "", "Forward", "FullLength" };
+      static XEvent event;
+      XtCallActionProc(scroll, "StartScroll", &event, params+1, 1);
+      XtCallActionProc(scroll, "NotifyScroll", &event, params+2, 1);
+      XtCallActionProc(scroll, "EndScroll", &event, params, 0);
+    }
   }
+  EvalGraphSet( first, last, current, pvInfoList ); // piggy-backed
 }
 
 Widget HistoryCreate()
@@ -326,37 +300,35 @@ Widget HistoryCreate()
              <Key>Right: ForwardProc() \n";
     /*--- allocate memory for move-strings ---*/
     HistoryAlloc(_LL_);
-   
+
     /*-------- create the widgets ---------------*/
     j = 0;
     XtSetArg(args[j], XtNresizable, True);  j++;
-    XtSetArg(args[j], XtNallowShellResize, True);  j++;   
+    XtSetArg(args[j], XtNallowShellResize, True);  j++;
 #if TOPLEVEL
-    hist->sh =
-      XtCreatePopupShell("Move list", topLevelShellWidgetClass,
+    hist->sh = historyShell =
+      XtCreatePopupShell(_("Move list"), topLevelShellWidgetClass,
                         shellWidget, args, j);
 #else
-    hist->sh =
-      XtCreatePopupShell("Move list", transientShellWidgetClass,
+    hist->sh = historyShell =
+      XtCreatePopupShell(_("Move list"), transientShellWidgetClass,
                         shellWidget, args, j);
-#endif        
+#endif
     j = 0;
     XtSetArg(args[j], XtNborderWidth, 0); j++;
     XtSetArg(args[j], XtNdefaultDistance, 0);  j++;
       layout =
       XtCreateManagedWidget(layoutName, formWidgetClass, hist->sh,
                            args, j);
-    
+
     j = 0;
     XtSetArg(args[j], XtNborderWidth, 0); j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
-  
+
     form =
       XtCreateManagedWidget("form", formWidgetClass, layout, args, j);
-     j=0;
 
     j = 0;
-
     XtSetArg(args[j], XtNtop, XtChainTop);  j++;
     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
@@ -376,13 +348,13 @@ Widget HistoryCreate()
     XtSetArg(args[j], XtNorientation,XtorientHorizontal);j++;
     hist->vbox =
       XtCreateManagedWidget("vbox", formWidgetClass, hist->viewport, args, j);
-    
+
     j=0;
     XtSetArg(args[j], XtNtop, XtChainTop);  j++;
     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
-    XtSetArg(args[j], XtNright, XtChainLeft);  j++;    
-     
+    XtSetArg(args[j], XtNright, XtChainLeft);  j++;
+
     XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
     XtSetArg(args[j], XtNforceColumns, True);  j++;
     XtSetArg(args[j], XtNverticalList, True);  j++;
@@ -397,8 +369,8 @@ Widget HistoryCreate()
     XtSetArg(args[j], XtNtop, XtChainTop);  j++;
     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
-    XtSetArg(args[j], XtNright, XtRubber);  j++;    
-    
+    XtSetArg(args[j], XtNright, XtRubber);  j++;
+
     XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
     XtSetArg(args[j], XtNforceColumns, True);  j++;
     XtSetArg(args[j], XtNverticalList, True);  j++;
@@ -414,7 +386,7 @@ Widget HistoryCreate()
     XtSetArg(args[j], XtNbottom, XtChainTop);  j++;
     XtSetArg(args[j], XtNleft, XtRubber);  j++;
     XtSetArg(args[j], XtNright,  XtRubber);  j++;
-    
+
     XtSetArg(args[j], XtNdefaultColumns, 1);  j++;
     XtSetArg(args[j], XtNforceColumns, True);  j++;
     XtSetArg(args[j], XtNverticalList, True);  j++;
@@ -431,20 +403,38 @@ Widget HistoryCreate()
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
     XtSetArg(args[j], XtNright, XtChainLeft);  j++;
     XtSetArg(args[j], XtNfromVert, hist->viewport);  j++;
-    b_close= XtCreateManagedWidget("Close", commandWidgetClass,
-                                  form, args, j);   
+    b_close= XtCreateManagedWidget(_("Close"), commandWidgetClass,
+                                  form, args, j);
     XtAddCallback(b_close, XtNcallback, HistoryPopDown, (XtPointer) 0);
 
-    XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr)); 
+    XtAugmentTranslations(hist->sh,XtParseTranslationTable (trstr));
 
     XtRealizeWidget(hist->sh);
     CatchDeleteWindow(hist->sh, "HistoryPopDown");
 
     for(i=1;i<hist->aNr;i++){
-      strcpy(hist->white[i],dots);
-      strcpy(hist->black[i],"");
+      safeStrCpy(hist->white[i],dots, MOVE_LEN);
+      safeStrCpy(hist->black[i],"", MOVE_LEN);
      }
-   
+
+    if(wpMoveHistory.width > 0) {
+      gameHistoryW = wpMoveHistory.width;
+      gameHistoryH = wpMoveHistory.height;
+      gameHistoryX = wpMoveHistory.x;
+      gameHistoryY = wpMoveHistory.y;
+    }
+
+  // [HGM] restore old position
+  if(gameHistoryW > 0) {
+  j = 0;
+    XtSetArg(args[j], XtNx, gameHistoryX);  j++;
+  XtSetArg(args[j], XtNy, gameHistoryY);  j++;
+    XtSetArg(args[j], XtNwidth, gameHistoryW);  j++;
+    XtSetArg(args[j], XtNheight, gameHistoryH);  j++;
+  XtSetValues(hist->sh, args, j);
+  }
+    XtRealizeWidget(hist->sh);
+
     return hist->sh;
 }
 
@@ -455,15 +445,17 @@ HistoryPopUp()
   int j;
 
   if(!hist) HistoryCreate();
+
   XtPopup(hist->sh, XtGrabNone);
+
   j=0;
   XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
-  XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Show Move List"),
+  XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Move History"),
                args, j);
   hist->Up=True;
 }
 
+
 void
 HistoryShowProc(w, event, prms, nprms)
      Widget w;
@@ -481,4 +473,9 @@ HistoryShowProc(w, event, prms, nprms)
   }
   ToNrEvent(currentMove);
 }
+
+Boolean
+MoveHistoryIsUp()
+{
+  return hist && hist->Up;
+}