* Massachusetts.
*
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009 Free Software Foundation, Inc.
+ * 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
*
* The following terms apply to Digital Equipment Corporation's copyright
* interest in XBoard:
} Menu;
int main P((int argc, char **argv));
+FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *failed,
+ char *init_path, char *mode, int (*show_entry)(), char **name_return));
RETSIGTYPE CmailSigHandler P((int sig));
RETSIGTYPE IntSigHandler P((int sig));
RETSIGTYPE TermSizeSigHandler P((int sig));
void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void EnterKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void UpKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void DownKeyProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void StopObservingProc P((Widget w, XEvent *event, String *prms,
Cardinal *nprms));
void StopExaminingProc P((Widget w, XEvent *event, String *prms,
Cardinal *nprms));
+void UploadProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
+void AnnotateProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
void TruncateGameProc P((Widget w, XEvent *event, String *prms,
Cardinal *nprms));
void RetractMoveProc P((Widget w, XEvent *event, String *prms,
menuBarWidget, buttonBarWidget, editShell, errorShell, analysisShell,
ICSInputShell, fileNameShell, askQuestionShell;
Widget historyShell, evalGraphShell, gameListShell;
+int hOffset; // [HGM] dual
+XSegment secondSegments[BOARD_RANKS + BOARD_FILES + 2];
XSegment gridSegments[BOARD_RANKS + BOARD_FILES + 2];
XSegment jailGridSegments[BOARD_RANKS + BOARD_FILES + 6];
Font clockFontID, coordFontID, countFontID;
{"----", NothingProc},
{N_("Stop Observing"), StopObservingProc},
{N_("Stop Examining"), StopExaminingProc},
+ {N_("Upload to Examine"), UploadProc},
{"----", NothingProc},
{N_("Adjudicate to White"), AdjuWhiteProc},
{N_("Adjudicate to Black"), AdjuBlackProc},
{N_("Back to Start"), ToStartProc},
{N_("Forward to End"), ToEndProc},
{N_("Revert"), RevertProc},
+ {N_("Annotate"), AnnotateProc},
{N_("Truncate Game"), TruncateGameProc},
{"----", NothingProc},
{N_("Move Now"), MoveNowProc},
{ "AdjuBlackProc", AdjuBlackProc },
{ "AdjuDrawProc", AdjuDrawProc },
{ "EnterKeyProc", EnterKeyProc },
+ { "UpKeyProc", UpKeyProc },
+ { "DownKeyProc", DownKeyProc },
{ "StopObservingProc", StopObservingProc },
{ "StopExaminingProc", StopExaminingProc },
+ { "UploadProc", UploadProc },
{ "BackwardProc", BackwardProc },
{ "ForwardProc", ForwardProc },
{ "ToStartProc", ToStartProc },
{ "ToEndProc", ToEndProc },
{ "RevertProc", RevertProc },
+ { "AnnotateProc", AnnotateProc },
{ "TruncateGameProc", TruncateGameProc },
{ "MoveNowProc", MoveNowProc },
{ "RetractMoveProc", RetractMoveProc },
char blackTranslations[] = "<BtnDown>: BlackClock()\n";
char ICSInputTranslations[] =
+ "<Key>Up: UpKeyProc() \n "
+ "<Key>Down: DownKeyProc() \n "
"<Key>Return: EnterKeyProc() \n";
String xboardResources[] = {
//--------------------------------------------------------------------------------------------
+extern Boolean twoBoards, partnerUp;
+
#ifdef IDSIZES
// eventually, all layout determining code should go into a subroutine, but until then IDSIZE remains undefined
#else
shellArgs[1].value = (XtArgVal) &h;
XtGetValues(shellWidget, shellArgs, 2);
- shellArgs[4].value = 2*w; shellArgs[2].value = 10;
+ shellArgs[4].value = 3*w; shellArgs[2].value = 10;
shellArgs[5].value = 2*h; shellArgs[3].value = 10;
XtSetValues(shellWidget, &shellArgs[2], 4);
boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap);
boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap);
CreateGrid();
+ hOffset = boardWidth + 10;
+ for(i=0; i<BOARD_WIDTH+BOARD_HEIGHT+2; i++) { // [HGM] dual: grid for second board
+ secondSegments[i] = gridSegments[i];
+ secondSegments[i].x1 += hOffset;
+ secondSegments[i].x2 += hOffset;
+ }
XtSetArg(args[0], XtNwidth, boardWidth);
XtSetArg(args[1], XtNheight, boardHeight);
/*
* Inhibit shell resizing.
*/
- shellArgs[0].value = w = (XtArgVal) boardWidth + marginW;
+ shellArgs[0].value = w = (XtArgVal) boardWidth + marginW + twoBoards*hOffset; // [HGM] dual
shellArgs[1].value = h = (XtArgVal) boardHeight + marginH;
shellArgs[4].value = shellArgs[2].value = w;
shellArgs[5].value = shellArgs[3].value = h;
} else {
XtSetSensitive(w, !grey);
}
+ w = XtNameToWidget(menuBarWidget, "menuStep.Annotate");
+ if (w == NULL) {
+ DisplayError("menuStep.Annotate", 0);
+ } else {
+ XtSetSensitive(w, !grey);
+ }
}
void
{ "menuOptions.Hide Thinking", False },
{ "menuOptions.Ponder Next Move", False },
#endif
+ { "menuStep.Annotate", False },
{ NULL, False }
};
{ "menuMode.ICS Input Box", False },
{ "Action", False },
{ "menuStep.Revert", False },
+ { "menuStep.Annotate", False },
{ "menuStep.Move Now", False },
{ "menuStep.Retract Move", False },
{ "menuOptions.Auto Comment", False },
{ "menuAction.Adjourn", False },
{ "menuAction.Stop Examining", False },
{ "menuAction.Stop Observing", False },
+ { "menuAction.Upload to Examine", False },
{ "menuStep.Revert", False },
+ { "menuStep.Annotate", False },
{ "menuOptions.Auto Comment", False },
{ "menuOptions.Auto Observe", False },
{ "menuOptions.Auto Raise Board", False },
}
}
+// [HGM] code borrowed from winboard.c (which should thus go to backend.c!)
+#define HISTORY_SIZE 64\r
+static char *history[HISTORY_SIZE];\r
+int histIn = 0, histP = 0;\r
+\r
+void\r
+SaveInHistory(char *cmd)\r
+{\r
+ if (history[histIn] != NULL) {\r
+ free(history[histIn]);\r
+ history[histIn] = NULL;\r
+ }\r
+ if (*cmd == NULLCHAR) return;\r
+ history[histIn] = StrSave(cmd);\r
+ histIn = (histIn + 1) % HISTORY_SIZE;\r
+ if (history[histIn] != NULL) {\r
+ free(history[histIn]);\r
+ history[histIn] = NULL;\r
+ }\r
+ histP = histIn;\r
+}\r
+\r
+char *\r
+PrevInHistory(char *cmd)\r
+{\r
+ int newhp;\r
+ if (histP == histIn) {\r
+ if (history[histIn] != NULL) free(history[histIn]);\r
+ history[histIn] = StrSave(cmd);\r
+ }\r
+ newhp = (histP - 1 + HISTORY_SIZE) % HISTORY_SIZE;\r
+ if (newhp == histIn || history[newhp] == NULL) return NULL;\r
+ histP = newhp;\r
+ return history[histP];\r
+}\r
+\r
+char *\r
+NextInHistory()\r
+{\r
+ if (histP == histIn) return NULL;\r
+ histP = (histP + 1) % HISTORY_SIZE;\r
+ return history[histP]; \r
+}
+// end of borrowed code\r
+\r
#define Abs(n) ((n)<0 ? -(n) : (n))
/*
(squareSize + lineGap);
}
+ if(twoBoards && partnerUp) x += hOffset; // [HGM] dual: draw second board
+
square_color = SquareColor(row, column);
if ( // [HGM] holdings: blank out area between board and holdings
x + 2, y + font_ascent + 1, string, 1);
}
}
- if(marker[row][column]) {
+ if(!partnerUp && marker[row][column]) {
XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC,
x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360);
}
case Expose:
if (event->xexpose.count > 0) return; /* no clipping is done */
XDrawPosition(widget, True, NULL);
+ if(twoBoards) { // [HGM] dual: draw other board in other orientation
+ flipView = !flipView; partnerUp = !partnerUp;
+ XDrawPosition(widget, True, NULL);
+ flipView = !flipView; partnerUp = !partnerUp;
+ }
break;
case MotionNotify:
if(SeekGraphClick(Press, event->xbutton.x, event->xbutton.y, 1)) break;\r
XDrawString(xDisplay, xBoardWindow, coordGC, x, y+4, buf, strlen(buf));
}
-void DrawSeekDot(int x, int y, int color)
+void DrawSeekDot(int x, int y, int colorNr)
{
- XFillArc(xDisplay, xBoardWindow, color == 0 ? prelineGC : color == 1 ? darkSquareGC : highlineGC,
+ int square = colorNr & 0x80;
+ GC color;
+ colorNr &= 0x7F;
+ color = colorNr == 0 ? prelineGC : colorNr == 1 ? darkSquareGC : highlineGC;
+ if(square)
+ XFillRectangle(xDisplay, xBoardWindow, color,
+ x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9);
+ else
+ XFillArc(xDisplay, xBoardWindow, color,
x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360);
}
-static int damage[BOARD_RANKS][BOARD_FILES];
+static int damage[2][BOARD_RANKS][BOARD_FILES];
/*
* event handler for redrawing the board
{
int i, j, do_flash;
static int lastFlipView = 0;
- static int lastBoardValid = 0;
- static Board lastBoard;
+ static int lastBoardValid[2] = {0, 0};
+ static Board lastBoard[2];
Arg args[16];
int rrow, rcol;
+ int nr = twoBoards*partnerUp;
if(DrawSeekGraph()) return; // [HGM] seekgraph: suppress any drawing if seek graph up
if (board == NULL) {
if (!lastBoardValid) return;
- board = lastBoard;
+ board = lastBoard[nr];
}
- if (!lastBoardValid || lastFlipView != flipView) {
+ if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) {
XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
args, 1);
* but this causes a very distracting flicker.
*/
- if (!repaint && lastBoardValid && lastFlipView == flipView) {
+ if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) {
/* If too much changes (begin observing new game, etc.), don't
do flashing */
- do_flash = too_many_diffs(board, lastBoard) ? 0 : 1;
+ do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1;
/* Special check for castling so we don't flash both the king
and the rook (just flash the king). */
if (do_flash) {
- if (check_castle_draw(board, lastBoard, &rrow, &rcol)) {
+ if (check_castle_draw(board, lastBoard[nr], &rrow, &rcol)) {
/* Draw rook with NO flashing. King will be drawn flashing later */
DrawSquare(rrow, rcol, board[rrow][rcol], 0);
- lastBoard[rrow][rcol] = board[rrow][rcol];
+ lastBoard[nr][rrow][rcol] = board[rrow][rcol];
}
}
is flashing on its new square */
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++)
- if ((board[i][j] != lastBoard[i][j] && board[i][j] == EmptySquare)
- || damage[i][j]) {
+ if ((board[i][j] != lastBoard[nr][i][j] && board[i][j] == EmptySquare)
+ || damage[nr][i][j]) {
DrawSquare(i, j, board[i][j], 0);
- damage[i][j] = False;
+ damage[nr][i][j] = False;
}
/* Second pass -- Draw piece(s) in new position and flash them */
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++)
- if (board[i][j] != lastBoard[i][j]) {
+ if (board[i][j] != lastBoard[nr][i][j]) {
DrawSquare(i, j, board[i][j], do_flash);
}
} else {
if (lineGap > 0)
XDrawSegments(xDisplay, xBoardWindow, lineGC,
+ twoBoards & partnerUp ? secondSegments : // [HGM] dual
gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2);
for (i = 0; i < BOARD_HEIGHT; i++)
for (j = 0; j < BOARD_WIDTH; j++) {
DrawSquare(i, j, board[i][j], 0);
- damage[i][j] = False;
+ damage[nr][i][j] = False;
}
}
- CopyBoard(lastBoard, board);
- lastBoardValid = 1;
+ CopyBoard(lastBoard[nr], board);
+ lastBoardValid[nr] = 1;
+ if(nr == 0) { // [HGM] dual: no highlights on second board yet
lastFlipView = flipView;
/* Draw highlights */
if (hi2X >= 0 && hi2Y >= 0) {
drawHighlight(hi2X, hi2Y, highlineGC);
}
-
+ }
/* If piece being dragged around board, must redraw that too */
DrawDragPiece();
j = 0;
XtSetArg(args[j], XtNstring, &val); j++;
XtGetValues(edit, args, j);
+ SaveInHistory(val);
SendMultiLineToICS(val);
XtCallActionProc(edit, "select-all", NULL, NULL, 0);
XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
fileProc = proc; /* I can't see a way not */
fileOpenMode = openMode; /* to use globals here */
-
- i = 0;
- XtSetArg(args[i], XtNresizable, True); i++;
- XtSetArg(args[i], XtNwidth, DIALOG_SIZE); i++;
- XtSetArg(args[i], XtNtitle, XtNewString(_("File name prompt"))); i++;
- fileNameShell = popup =
- XtCreatePopupShell("File name prompt", transientShellWidgetClass,
- shellWidget, args, i);
-
- layout =
- XtCreateManagedWidget(layoutName, formWidgetClass, popup,
- layoutArgs, XtNumber(layoutArgs));
-
- i = 0;
- XtSetArg(args[i], XtNlabel, label); i++;
- XtSetArg(args[i], XtNvalue, def); i++;
- XtSetArg(args[i], XtNborderWidth, 0); i++;
- dialog = XtCreateManagedWidget("fileName", dialogWidgetClass,
- layout, args, i);
-
- XawDialogAddButton(dialog, _("ok"), FileNameCallback, (XtPointer) dialog);
- XawDialogAddButton(dialog, _("cancel"), FileNameCallback,
- (XtPointer) dialog);
-
- XtRealizeWidget(popup);
- CatchDeleteWindow(popup, "FileNamePopDown");
-
- XQueryPointer(xDisplay, xBoardWindow, &root, &child,
- &x, &y, &win_x, &win_y, &mask);
-
- XtSetArg(args[0], XtNx, x - 10);
- XtSetArg(args[1], XtNy, y - 30);
- XtSetValues(popup, args, 2);
-
- XtPopup(popup, XtGrabExclusive);
- filenameUp = True;
-
- edit = XtNameToWidget(dialog, "*value");
- XtSetKeyboardFocus(popup, edit);
+ { // [HGM] use file-selector dialog stolen from Ghostview
+ char *name;
+ int index; // this is not supported yet
+ FILE *f;
+ if(f = XsraSelFile(shellWidget, label, NULL, NULL, "could not open: ",
+ NULL, openMode, NULL, &name))
+ (void) (*fileProc)(f, index=0, name);
+ }
}
void FileNamePopDown()
ICSInputSendText();
}
+void UpKeyProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{ // [HGM] input: let up-arrow recall previous line from history
+ Widget edit;
+ int j;
+ Arg args[16];
+ String val;
+ XawTextBlock t;
+
+ if (!ICSInputBoxUp) return;
+ edit = XtNameToWidget(ICSInputShell, "*form.text");
+ j = 0;
+ XtSetArg(args[j], XtNstring, &val); j++;
+ XtGetValues(edit, args, j);
+ val = PrevInHistory(val);
+ XtCallActionProc(edit, "select-all", NULL, NULL, 0);
+ XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
+ if(val) {
+ t.ptr = val; t.firstPos = 0; t.length = strlen(val); t.format = XawFmt8Bit;
+ XawTextReplace(edit, 0, 0, &t);
+ XawTextSetInsertionPoint(edit, 9999);
+ }
+}
+
+void DownKeyProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{ // [HGM] input: let down-arrow recall next line from history
+ Widget edit;
+ String val;
+ XawTextBlock t;
+
+ if (!ICSInputBoxUp) return;
+ edit = XtNameToWidget(ICSInputShell, "*form.text");
+ val = NextInHistory();
+ XtCallActionProc(edit, "select-all", NULL, NULL, 0);
+ XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
+ if(val) {
+ t.ptr = val; t.firstPos = 0; t.length = strlen(val); t.format = XawFmt8Bit;
+ XawTextReplace(edit, 0, 0, &t);
+ XawTextSetInsertionPoint(edit, 9999);
+ }
+}
+
void StopObservingProc(w, event, prms, nprms)
Widget w;
XEvent *event;
StopExaminingEvent();
}
+void UploadProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{
+ UploadGameEvent();
+}
+
void ForwardProc(w, event, prms, nprms)
Widget w;
String *prms;
Cardinal *nprms;
{
- RevertEvent();
+ RevertEvent(False);
+}
+
+void AnnotateProc(w, event, prms, nprms)
+ Widget w;
+ XEvent *event;
+ String *prms;
+ Cardinal *nprms;
+{
+ RevertEvent(True);
}
void TruncateGameProc(w, event, prms, nprms)
FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames);
/* Be sure end square is redrawn */
- damage[toY][toX] = True;
+ damage[0][toY][toX] = True;
}
void
XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
corner.x, corner.y, squareSize, squareSize,
0, 0); // [HGM] zh: unstack in stead of grab
- damage[boardY][boardX] = True;
+ damage[0][boardY][boardX] = True;
} else {
player.dragActive = False;
}
EndAnimation(&player, &corner);
/* Be sure end square is redrawn */
- damage[boardY][boardX] = True;
+ damage[0][boardY][boardX] = True;
/* This prevents weird things happening with fast successive
clicks which on my Sun at least can cause motion events
BlankSquare(player.startSquare.x, player.startSquare.y,
player.startColor, EmptySquare, xBoardWindow);
AnimationFrame(&player, &player.prevFrame, player.dragPiece);
- damage[player.startBoardY][player.startBoardX] = TRUE;
+ damage[0][player.startBoardY][player.startBoardX] = TRUE;
}
#include <sys/ioctl.h>