* xboard.c -- X front end for XBoard
*
* Copyright 1991 by Digital Equipment Corporation, Maynard,
- * Massachusetts.
+ * Massachusetts.
*
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
* 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
# endif
#endif
+
+# if HAVE_LIBREADLINE /* add gnu-readline support */
+#include <readline/readline.h>
+#include <readline/history.h>
+# endif
+
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include "frontend.h"
#include "backend.h"
+#include "backendz.h"
#include "moves.h"
#include "xboard.h"
#include "childio.h"
} 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));
String * params, Cardinal * nParams));
void HandlePV P((Widget w, XEvent * event,
String * params, Cardinal * nParams));
+void SelectPV P((Widget w, XEvent * event,
+ String * params, Cardinal * nParams));
+void StopPV P((Widget w, XEvent * event,
+ String * params, Cardinal * nParams));
void WhiteClock P((Widget w, XEvent *event,
String *prms, Cardinal *nprms));
void BlackClock P((Widget w, XEvent *event,
String *prms, Cardinal *nprms));
void XDrawPosition P((Widget w, /*Boolean*/int repaint,
Board board));
+void CommentClick P((Widget w, XEvent * event,
+ String * params, Cardinal * nParams));
void CommentPopUp P((char *title, char *label));
void CommentPopDown P((void));
void CommentCallback P((Widget w, XtPointer client_data,
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,
void update_ics_width P(());
int get_term_width P(());
int CopyMemoProc P(());
+
+# if HAVE_LIBREADLINE /* add gnu-readline support */
+static void ReadlineCompleteHandler P((char *));
+# endif
+
/*
* XBoard depends on Xt R4 or higher
*/
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;
char *fileOpenMode;
char installDir[] = "."; // [HGM] UCI: needed for UCI; probably needs run-time initializtion
+# if HAVE_LIBREADLINE /* gnu readline support */
+static char* readline_buffer;
+static int readline_complete=0;
+extern int sending_ICS_login;
+extern int sending_ICS_password;
+#endif
+
Position commentX = -1, commentY = -1;
Dimension commentW, commentH;
typedef unsigned int BoardSize;
{"----", 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},
#define PIECE_MENU_SIZE 18
String pieceMenuStrings[2][PIECE_MENU_SIZE] = {
{ N_("White"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
- N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
- N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
+ N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
+ N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
N_("Empty square"), N_("Clear board") },
{ N_("Black"), "----", N_("Pawn"), N_("Knight"), N_("Bishop"), N_("Rook"),
- N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
- N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
+ N_("Queen"), N_("King"), "----", N_("Elephant"), N_("Cannon"),
+ N_("Archbishop"), N_("Chancellor"), "----", N_("Promote"), N_("Demote"),
N_("Empty square"), N_("Clear board") }
};
/* must be in same order as PieceMenuStrings! */
ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
{ WhitePlay, (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
WhiteRook, WhiteQueen, WhiteKing, (ChessSquare) 0, WhiteAlfil,
- WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
+ WhiteCannon, WhiteAngel, WhiteMarshall, (ChessSquare) 0,
PromotePiece, DemotePiece, EmptySquare, ClearBoard },
{ BlackPlay, (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
BlackRook, BlackQueen, BlackKing, (ChessSquare) 0, BlackAlfil,
- BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
+ BlackCannon, BlackAngel, BlackMarshall, (ChessSquare) 0,
PromotePiece, DemotePiece, EmptySquare, ClearBoard },
};
{ "HandleUserMove", HandleUserMove },
{ "AnimateUserMove", AnimateUserMove },
{ "HandlePV", HandlePV },
- { "UnLoadPV", UnLoadPV },
+ { "SelectPV", SelectPV },
+ { "StopPV", StopPV },
{ "FileNameAction", FileNameAction },
{ "AskQuestionProc", AskQuestionProc },
{ "AskQuestionReplyAction", AskQuestionReplyAction },
{ "BlackClock", BlackClock },
{ "Iconify", Iconify },
{ "ResetProc", ResetProc },
+ { "NewVariantProc", NewVariantProc },
{ "LoadGameProc", LoadGameProc },
{ "LoadNextGameProc", LoadNextGameProc },
{ "LoadPrevGameProc", LoadPrevGameProc },
{ "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 },
+ { "EngineMenuProc", (XtActionProc) EngineMenuProc },
+ { "UciMenuProc", (XtActionProc) UciMenuProc },
+ { "TimeControlProc", (XtActionProc) TimeControlProc },
{ "AlwaysQueenProc", AlwaysQueenProc },
{ "AnimateDraggingProc", AnimateDraggingProc },
{ "AnimateMovingProc", AnimateMovingProc },
{ "AboutProc", AboutProc },
{ "DebugProc", DebugProc },
{ "NothingProc", NothingProc },
+ { "CommentClick", (XtActionProc) CommentClick },
{ "CommentPopDown", (XtActionProc) CommentPopDown },
{ "EditCommentPopDown", (XtActionProc) EditCommentPopDown },
{ "TagsPopDown", (XtActionProc) TagsPopDown },
};
char globalTranslations[] =
- ":<Key>R: ResignProc() \n \
- :<Key>r: ResetProc() \n \
- :<Key>g: LoadGameProc() \n \
- :<Key>N: LoadNextGameProc() \n \
- :<Key>P: LoadPrevGameProc() \n \
- :<Key>Q: QuitProc() \n \
- :<Key>F: ToEndProc() \n \
- :<Key>f: ForwardProc() \n \
- :<Key>B: ToStartProc() \n \
- :<Key>b: BackwardProc() \n \
- :<Key>p: PauseProc() \n \
- :<Key>d: DrawProc() \n \
- :<Key>t: CallFlagProc() \n \
- :<Key>i: Iconify() \n \
- :<Key>c: Iconify() \n \
- :<Key>v: FlipViewProc() \n \
- <KeyDown>Control_L: BackwardProc() \n \
- <KeyUp>Control_L: ForwardProc() \n \
- <KeyDown>Control_R: BackwardProc() \n \
- <KeyUp>Control_R: ForwardProc() \n \
+ ":<Key>F9: ResignProc() \n \
+ :Ctrl<Key>n: ResetProc() \n \
+ :Meta<Key>V: NewVariantProc() \n \
+ :Ctrl<Key>o: LoadGameProc() \n \
+ :Meta<Key>Next: LoadNextGameProc() \n \
+ :Meta<Key>Prior: LoadPrevGameProc() \n \
+ :Ctrl<Key>s: SaveGameProc() \n \
+ :Ctrl<Key>c: CopyGameProc() \n \
+ :Ctrl<Key>v: PasteGameProc() \n \
+ :Ctrl<Key>O: LoadPositionProc() \n \
+ :Shift Meta<Key>Next: LoadNextPositionProc() \n \
+ :Shift Meta<Key>Prior: LoadPrevPositionProc() \n \
+ :Ctrl<Key>S: SavePositionProc() \n \
+ :Ctrl<Key>C: CopyPositionProc() \n \
+ :Ctrl<Key>V: PastePositionProc() \n \
+ :Ctrl<Key>q: QuitProc() \n \
+ :Ctrl<Key>w: MachineWhiteProc() \n \
+ :Ctrl<Key>b: MachineBlackProc() \n \
+ :Ctrl<Key>t: TwoMachinesProc() \n \
+ :Ctrl<Key>a: AnalysisModeProc() \n \
+ :Ctrl<Key>f: AnalyzeFileProc() \n \
+ :Ctrl<Key>e: EditGameProc() \n \
+ :Ctrl<Key>E: EditPositionProc() \n \
+ :Meta<Key>O: EngineOutputProc() \n \
+ :Meta<Key>E: EvalGraphProc() \n \
+ :Meta<Key>G: ShowGameListProc() \n \
+ :Meta<Key>H: ShowMoveListProc() \n \
+ :<Key>Pause: PauseProc() \n \
+ :<Key>F3: AcceptProc() \n \
+ :<Key>F4: DeclineProc() \n \
+ :<Key>F12: RematchProc() \n \
+ :<Key>F5: CallFlagProc() \n \
+ :<Key>F6: DrawProc() \n \
+ :<Key>F7: AdjournProc() \n \
+ :<Key>F8: AbortProc() \n \
+ :<Key>F10: StopObservingProc() \n \
+ :<Key>F11: StopExaminingProc() \n \
+ :Meta Ctrl<Key>F12: DebugProc() \n \
+ :Meta<Key>End: ToEndProc() \n \
+ :Meta<Key>Right: ForwardProc() \n \
+ :Meta<Key>Home: ToStartProc() \n \
+ :Meta<Key>Left: BackwardProc() \n \
+ :Ctrl<Key>m: MoveNowProc() \n \
+ :Ctrl<Key>x: RetractMoveProc() \n \
+ :Meta<Key>J: EngineMenuProc() \n \
+ :Meta<Key>U: UciMenuProc() \n \
+ :Meta<Key>T: TimeControlProc() \n \
+ :Ctrl<Key>Q: AlwaysQueenProc() \n \
+ :Ctrl<Key>F: AutoflagProc() \n \
+ :Ctrl<Key>A: AnimateMovingProc() \n \
+ :Ctrl<Key>P: PonderNextMoveProc() \n \
+ :Ctrl<Key>L: TestLegalityProc() \n \
+ :Ctrl<Key>H: HideThinkingProc() \n \
+ :<Key>-: Iconify() \n \
+ :<Key>F1: ManProc() \n \
+ :<Key>F2: FlipViewProc() \n \
+ <KeyDown>.: BackwardProc() \n \
+ <KeyUp>.: ForwardProc() \n \
Shift<Key>1: AskQuestionProc(\"Direct command\",\
\"Send to chess program:\",,1) \n \
Shift<Key>2: AskQuestionProc(\"Direct command\",\
\"Send to second chess program:\",,2) \n";
char boardTranslations[] =
- "<Btn1Down>: HandleUserMove() \n \
- <Btn1Up>: HandleUserMove() \n \
+ "<Btn1Down>: HandleUserMove(0) \n \
+ Shift<Btn1Up>: HandleUserMove(1) \n \
+ <Btn1Up>: HandleUserMove(0) \n \
<Btn1Motion>: AnimateUserMove() \n \
<Btn3Motion>: HandlePV() \n \
<Btn3Up>: PieceMenuPopup(menuB) \n \
char blackTranslations[] = "<BtnDown>: BlackClock()\n";
char ICSInputTranslations[] =
+ "<Key>Up: UpKeyProc() \n "
+ "<Key>Down: DownKeyProc() \n "
"<Key>Return: EnterKeyProc() \n";
+// [HGM] vari: another hideous kludge: call extend-end first so we can be sure select-start works,
+// as the widget is destroyed before the up-click can call extend-end
+char commentTranslations[] = "<Btn3Down>: extend-end() select-start() CommentClick() \n";
+
String xboardResources[] = {
"*fileName*value.translations: #override\\n <Key>Return: FileNameAction()",
"*question*value.translations: #override\\n <Key>Return: AskQuestionReplyAction()",
void *
colorVariable[] = {
- &appData.whitePieceColor,
- &appData.blackPieceColor,
+ &appData.whitePieceColor,
+ &appData.blackPieceColor,
&appData.lightSquareColor,
- &appData.darkSquareColor,
+ &appData.darkSquareColor,
&appData.highlightSquareColor,
&appData.premoveHighlightColor,
&appData.lowTimeWarningColor,
void
ParseTextAttribs(ColorClass cc, char *s)
-{
+{
(&appData.colorShout)[cc] = strdup(s);
}
void
SaveFontArg(FILE *f, ArgDescriptor *ad)
{
- char *name, buf[MSG_SIZ];
+ char *name;
int i, n = (int)ad->argLoc;
switch(n) {
case 0: // CLOCK_FONT
break;
}
for(i=0; i<MAX_SIZE; i++) if(fontValid[n][i]) // [HGM] font: store all standard fonts
- fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]);
+ fprintf(f, OPTCHAR "%s" SEPCHAR "size%d:%s\n", ad->argName, i, fontTable[n][i]);
}
void
int i;
if(!wg) return;
-
+
i = 0;
XtSetArg(args[i], XtNx, &x); i++;
XtSetArg(args[i], XtNy, &y); i++;
MySearchPath(char *installDir, char *name, char *fullname)
{ // just append installDir and name. Perhaps ExpandPath should be used here?
name = ExpandPathName(name);
- if(name && name[0] == '/') strcpy(fullname, name); else {
+ if(name && name[0] == '/')
+ safeStrCpy(fullname, name, MSG_SIZ );
+ else {
sprintf(fullname, "%s%c%s", installDir, '/', name);
}
return 1;
MyGetFullPathName(char *name, char *fullname)
{ // should use ExpandPath?
name = ExpandPathName(name);
- strcpy(fullname, name);
+ safeStrCpy(fullname, name, MSG_SIZ );
return 1;
}
PopUpStartupDialog()
{ // start menu not implemented in XBoard
}
+
char *
ConvertToLine(int argc, char **argv)
{
int i;
line[0] = NULLCHAR;
- for(i=1; i<argc; i++) {
- if( (strchr(argv[i], ' ') || strchr(argv[i], '\n') ||strchr(argv[i], '\t') )
- && argv[i][0] != '{' )
- sprintf(buf, "{%s} ", argv[i]);
- else sprintf(buf, "%s ", argv[i]);
- strcat(line, buf);
- }
- line[strlen(line)-1] = NULLCHAR;
+ for(i=1; i<argc; i++)
+ {
+ if( (strchr(argv[i], ' ') || strchr(argv[i], '\n') ||strchr(argv[i], '\t') )
+ && argv[i][0] != '{' )
+ snprintf(buf, sizeof(buf)/sizeof(buf[0]), "{%s} ", argv[i]);
+ else
+ snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s ", argv[i]);
+ strncat(line, buf, 128*1024 - strlen(line) - 1 );
+ }
+
+ line[strlen(line)-1] = NULLCHAR;
return line;
}
//--------------------------------------------------------------------------------------------
+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;
}
#endif
-void EscapeExpand(char *p, char *q)
-{ // [HGM] initstring: routine to shape up string arguments
- while(*p++ = *q++) if(p[-1] == '\\')
- switch(*q++) {
- case 'n': p[-1] = '\n'; break;
- case 'r': p[-1] = '\r'; break;
- case 't': p[-1] = '\t'; break;
- case '\\': p[-1] = '\\'; break;
- case 0: *p = 0; return;
- default: p[-1] = q[-1]; break;
- }
-}
-
int
main(argc, argv)
int argc;
setbuf(stdout, NULL);
setbuf(stderr, NULL);
debugFP = stderr;
+
+# if HAVE_LIBREADLINE
+ /* install gnu-readline handler */
+ rl_callback_handler_install("> ", ReadlineCompleteHandler);
+ rl_readline_name="XBoard";
+# endif
if(argc > 1 && (!strcmp(argv[1], "-v" ) || !strcmp(argv[1], "--version" ))) {
printf("%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
if (forceMono) {
fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"),
programName);
-
+
if (appData.bitmapDirectory == NULL ||
appData.bitmapDirectory[0] == NULLCHAR)
appData.bitmapDirectory = DEF_BITMAP_DIR;
vFrom.addr = (caddr_t) appData.lowTimeWarningColor;
vFrom.size = strlen(appData.lowTimeWarningColor);
XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
- if (vTo.addr == NULL)
+ if (vTo.addr == NULL)
appData.monoMode = True;
else
lowTimeWarningColor = *(Pixel *) vTo.addr;
HistoryPopUp();
}
- if( wpEvalGraph.visible )
+ if( wpEvalGraph.visible )
{
EvalGraphPopUp();
};
-
+
if( wpEngineOutput.visible ) {
EngineOutputPopUp();
}
}
gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes()
InitPosition(TRUE);
+ XtSetKeyboardFocus(shellWidget, formWidget);
XtAppMainLoop(appContext);
if (appData.debugMode) fclose(debugFP); // [DM] debug
if (saveSettingsOnExit) SaveSettings(settingsFileName);
unlink(gameCopyFilename);
unlink(gamePasteFilename);
+
+# if HAVE_LIBREADLINE
+ /* remove gnu-readline handler. */
+ rl_callback_handler_remove();
+#endif
+
+ return;
}
RETSIGTYPE TermSizeSigHandler(int sig)
void
ICSInitScript()
{
- FILE *f;
- char buf[MSG_SIZ];
- char *p;
+ /* try to open the icsLogon script, either in the location given
+ * or in the users HOME directory
+ */
- f = fopen(appData.icsLogon, "r");
- if (f == NULL) {
- p = getenv("HOME");
- if (p != NULL) {
- strcpy(buf, p);
- strcat(buf, "/");
- strcat(buf, appData.icsLogon);
- f = fopen(buf, "r");
+ FILE *f;
+ char buf[MSG_SIZ];
+ char *homedir;
+
+ f = fopen(appData.icsLogon, "r");
+ if (f == NULL)
+ {
+ homedir = getenv("HOME");
+ if (homedir != NULL)
+ {
+ safeStrCpy(buf, homedir, sizeof(buf)/sizeof(buf[0]) );
+ strncat(buf, "/", MSG_SIZ - strlen(buf) - 1);
+ strncat(buf, appData.icsLogon, MSG_SIZ - strlen(buf) - 1);
+ f = fopen(buf, "r");
}
}
- if (f != NULL)
- ProcessICSInitScript(f);
+
+ if (f != NULL)
+ ProcessICSInitScript(f);
+ else
+ printf("Warning: Couldn't open icsLogon file (checked %s and %s).\n", appData.icsLogon, buf);
+
+ return;
}
void
} 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 },
{
SetMenuEnables(icsEnables);
-#ifdef ZIPPY
+#if ZIPPY
if (appData.zippyPlay && !appData.noChessProgram) /* [DM] icsEngineAnalyze */
XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
#endif
}
}
+// [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))
/*
* The return value should be freed with XtFree when no
* longer needed.
*/
-char *FindFont(pattern, targetPxlSize)
+char *
+FindFont(pattern, targetPxlSize)
char *pattern;
int targetPxlSize;
{
XFontStruct **fnt_list;
base_fnt_lst = calloc(1, strlen(pattern) + 3);
- sprintf(strInt, "%d", targetPxlSize);
+ snprintf(strInt, sizeof(strInt)/sizeof(strInt[0]), "%d", targetPxlSize);
p = strstr(pattern, "--");
strncpy(base_fnt_lst, pattern, p - pattern + 2);
strcat(base_fnt_lst, strInt);
while (isdigit(*scalableTail)) scalableTail++;
sprintf(p, "%.*s%d%s", headlen, scalable, targetPxlSize, scalableTail);
} else {
- p = (char *) XtMalloc(strlen(best) + 1);
- strcpy(p, best);
+ p = (char *) XtMalloc(strlen(best) + 2);
+ safeStrCpy(p, best, strlen(best)+1 );
}
if (appData.debugMode) {
fprintf(debugFP, _("resolved %s at pixel size %d\n to %s\n"),
exit(1);
}
}
- if(piece <= (int) WhiteKing)
+ if(piece <= (int) WhiteKing)
xpmPieceBitmap[kind][piece] = xpmPieceBitmap2[kind][piece];
}
}
for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
- sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
- pieceBitmapNames[piece],
- ss, kind == SOLID ? 's' : 'o');
- ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss);
- if(piece <= (int)WhiteKing)
- pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
+ snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
+ pieceBitmapNames[piece],
+ ss, kind == SOLID ? 's' : 'o');
+ ReadBitmap(&pieceBitmap2[kind][piece], buf, NULL, ss, ss);
+ if(piece <= (int)WhiteKing)
+ pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
}
}
for (kind = SOLID; kind <= (appData.monoMode ? OUTLINE : SOLID); kind++) {
for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) {
- sprintf(buf, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
- pieceBitmapNames[piece],
- ss, kind == SOLID ? 's' : 'o');
- ReadBitmap(&pieceBitmap2[kind][piece], buf,
- bib->bits[kind][piece], ss, ss);
- if(piece <= (int)WhiteKing)
- pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
+ snprintf(buf, MSG_SIZ, "%s%c%u%c.bm", piece > (int)WhiteKing ? "w" : "",
+ pieceBitmapNames[piece],
+ ss, kind == SOLID ? 's' : 'o');
+ ReadBitmap(&pieceBitmap2[kind][piece], buf,
+ bib->bits[kind][piece], ss, ss);
+ if(piece <= (int)WhiteKing)
+ pieceBitmap[kind][piece] = pieceBitmap2[kind][piece];
}
}
char msg[MSG_SIZ], fullname[MSG_SIZ];
if (*appData.bitmapDirectory != NULLCHAR) {
- strcpy(fullname, appData.bitmapDirectory);
- strcat(fullname, "/");
- strcat(fullname, name);
- errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
- &w, &h, pm, &x_hot, &y_hot);
- fprintf(stderr, "load %s\n", name);
+ safeStrCpy(fullname, appData.bitmapDirectory, sizeof(fullname)/sizeof(fullname[0]) );
+ strncat(fullname, "/", MSG_SIZ - strlen(fullname) - 1);
+ strncat(fullname, name, MSG_SIZ - strlen(fullname) - 1);
+ errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
+ &w, &h, pm, &x_hot, &y_hot);
+ fprintf(stderr, "load %s\n", name);
if (errcode != BitmapSuccess) {
switch (errcode) {
case BitmapOpenFailed:
formWidget, args, j);
while (mb->name != NULL) {
- strcpy(menuName, "menu");
- strcat(menuName, mb->name);
+ safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) );
+ strncat(menuName, mb->name, MSG_SIZ - strlen(menuName) - 1);
j = 0;
XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++;
if (tinyLayout) {
{
String whichMenu; int menuNr;
if (event->type == ButtonRelease)
- menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
+ menuNr = RightClick(Release, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
else if (event->type == ButtonPress)
menuNr = RightClick(Press, event->xbutton.x, event->xbutton.y, &pmFromX, &pmFromY);
switch(menuNr) {
}
break;
}
+ if(appData.upsideDown && flipView) kind ^= 2; // swap white and black pieces
XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
dest, wlPieceGC, 0, 0,
squareSize, squareSize, x, y);
(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]) {
- XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC,
+ 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
return 0;
}
-// [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph
+// [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph
void DrawSeekAxis( int x, int y, int xTo, int yTo )
{
XDrawLine(xDisplay, xBoardWindow, lineGC, x, y, xTo, yTo);
XFillRectangle(xDisplay, xBoardWindow, color,
x-squareSize/9, y-squareSize/9, 2*squareSize/9, 2*squareSize/9);
else
- XFillArc(xDisplay, xBoardWindow, color,
+ 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;
+ if (!lastBoardValid[nr]) return;
+ 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();
Cardinal *nprms;
{
if (w != boardWidget || errorExitStatus != -1) return;
+ if(nprms) shiftKey = !strcmp(prms[0], "1");
if (promotionUp) {
if (event->type == ButtonPress) {
XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
edit =
XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
+ XtOverrideTranslations(edit, XtParseTranslationTable(commentTranslations));
if (mutable) {
j = 0;
static int savedIndex; /* gross that this is global */
+void CommentClick (Widget w, XEvent * event, String * params, Cardinal * nParams)
+{
+ String val;
+ XawTextPosition index, dummy;
+ Arg arg;
+
+ XawTextGetSelectionPos(w, &index, &dummy);
+ XtSetArg(arg, XtNstring, &val);
+ XtGetValues(w, &arg, 1);
+ ReplaceComment(savedIndex, val);
+ if(savedIndex != currentMove) ToNrEvent(savedIndex);
+ LoadVariation( index, val ); // [HGM] also does the actual moving to it, now
+}
+
void EditCommentPopUp(index, title, text)
int index;
char *title, *text;
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);
int j;
Widget edit;
+ savedIndex = currentMove; // [HGM] vari
if (commentShell == NULL) {
commentShell =
CommentCreate(title, text, False, CommentCallback, 4);
FileProc proc;
char *openMode;
{
- Arg args[16];
- Widget popup, layout, dialog, edit;
- Window root, child;
- int x, y, i;
- int win_x, win_y;
- unsigned int mask;
-
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: ",
+ def, openMode, NULL, &name))
+ (void) (*fileProc)(f, index=0, name);
+ }
}
void FileNamePopDown()
name = XawDialogGetValueString(w = XtParent(w));
if ((name != NULL) && (*name != NULLCHAR)) {
- strcpy(buf, name);
+ safeStrCpy(buf, name, sizeof(buf)/sizeof(buf[0]) );
XtPopdown(w = XtParent(XtParent(w)));
XtDestroyWidget(w);
filenameUp = False;
XawDialogAddButton(dialog, _("King"), PromotionCallback,
(XtPointer) dialog);
}
- if(gameInfo.variant == VariantCapablanca ||
- gameInfo.variant == VariantGothic ||
+ if(gameInfo.variant == VariantCapablanca ||
+ gameInfo.variant == VariantGothic ||
gameInfo.variant == VariantCapaRandom) {
XawDialogAddButton(dialog, _("Archbishop"), PromotionCallback,
(XtPointer) dialog);
* automatically call XtFree on the value returned. So have to
* make a copy of it allocated with XtMalloc */
selection_tmp= XtMalloc(strlen(selected_fen_position)+16);
- strcpy(selection_tmp, selected_fen_position);
+ safeStrCpy(selection_tmp, selected_fen_position, sizeof(selection_tmp)/sizeof(selection_tmp[0]) );
*value_return=selection_tmp;
*length_return=strlen(selection_tmp);
String *prms;
Cardinal *nprms;
{
- XtGetSelectionValue(menuBarWidget,
+ XtGetSelectionValue(menuBarWidget,
appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING,
/* (XtSelectionCallbackProc) */ PastePositionCB,
NULL, /* client_data passed to PastePositionCB */
/* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */
if (appData.icsActive) {
if (gameMode != IcsObserving) {
- sprintf(buf,_("You are not observing a game"));
+ snprintf(buf, MSG_SIZ, _("You are not observing a game"));
DisplayError(buf, 0);
/* secure check */
if (appData.icsEngineAnalyze) {
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)
char *message, *extMessage;
{
/* display a message in the message widget */
-
+
char buf[MSG_SIZ];
Arg arg;
-
- if (extMessage)
+
+ if (extMessage)
{
- if (*message)
+ if (*message)
{
snprintf(buf, sizeof(buf), "%s %s", message, extMessage);
message = buf;
- }
- else
+ }
+ else
{
message = extMessage;
};
};
-
+
/* need to test if messageWidget already exists, since this function
can also be called during the startup, if for example a Xresource
is not set up correctly */
XtSetArg(arg, XtNlabel, message);
XtSetValues(messageWidget, &arg, 1);
};
-
+
return;
}
}
if (*text != NULLCHAR) {
- strcpy(icon, text);
- strcpy(title, text);
+ safeStrCpy(icon, text, sizeof(icon)/sizeof(icon[0]) );
+ safeStrCpy(title, text, sizeof(title)/sizeof(title[0]) );
} else if (appData.icsActive) {
snprintf(icon, sizeof(icon), "%s", appData.icsHost);
snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost);
#ifdef GOTHIC
// [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
} else if (gameInfo.variant == VariantGothic) {
- strcpy(icon, programName);
- strcpy(title, GOTHIC);
+ safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) );
+ safeStrCpy(title, GOTHIC, sizeof(title)/sizeof(title[0]) );
#endif
#ifdef FALCON
} else if (gameInfo.variant == VariantFalcon) {
- strcpy(icon, programName);
- strcpy(title, FALCON);
+ safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) );
+ safeStrCpy(title, FALCON, sizeof(title)/sizeof(title[0]) );
#endif
} else if (appData.noChessProgram) {
- strcpy(icon, programName);
- strcpy(title, programName);
+ safeStrCpy(icon, programName, sizeof(icon)/sizeof(icon[0]) );
+ safeStrCpy(title, programName, sizeof(title)/sizeof(title[0]) );
} else {
- strcpy(icon, first.tidy);
+ safeStrCpy(icon, first.tidy, sizeof(icon)/sizeof(icon[0]) );
snprintf(title,sizeof(title), "%s: %s", programName, first.tidy);
}
i = 0;
}
-void DisplayError(message, error)
+void
+DisplayError(message, error)
String message;
int error;
{
String reply;
reply = XawDialogGetValueString(w = XtParent(w));
- strcpy(buf, pendingReplyPrefix);
- if (*buf) strcat(buf, " ");
- strcat(buf, reply);
- strcat(buf, "\n");
+ safeStrCpy(buf, pendingReplyPrefix, sizeof(buf)/sizeof(buf[0]) );
+ if (*buf) strncat(buf, " ", MSG_SIZ - strlen(buf) - 1);
+ strncat(buf, reply, MSG_SIZ - strlen(buf) - 1);
+ strncat(buf, "\n", MSG_SIZ - strlen(buf) - 1);
OutputToProcess(pendingReplyPR, buf, strlen(buf), &err);
AskQuestionPopDown();
int win_x, win_y;
unsigned int mask;
- strcpy(pendingReplyPrefix, replyPrefix);
+ safeStrCpy(pendingReplyPrefix, replyPrefix, sizeof(pendingReplyPrefix)/sizeof(pendingReplyPrefix[0]) );
pendingReplyPR = pr;
i = 0;
if (textColors[(int)cc].bg > 0) {
if (textColors[(int)cc].fg > 0) {
- sprintf(buf, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].fg, textColors[(int)cc].bg);
+ snprintf(buf, MSG_SIZ, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
+ textColors[(int)cc].fg, textColors[(int)cc].bg);
} else {
- sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].bg);
+ snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
+ textColors[(int)cc].bg);
}
} else {
if (textColors[(int)cc].fg > 0) {
- sprintf(buf, "\033[0;%d;%dm", textColors[(int)cc].attr,
+ snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
textColors[(int)cc].fg);
} else {
- sprintf(buf, "\033[0;%dm", textColors[(int)cc].attr);
+ snprintf(buf, MSG_SIZ, "\033[0;%dm", textColors[(int)cc].attr);
}
}
count = strlen(buf);
return getpwuid(getuid())->pw_name;
}
-static char *ExpandPathName(path)
+static char *
+ExpandPathName(path)
char *path;
{
- static char static_buf[2000];
- char *d, *s, buf[2000];
+ static char static_buf[4*MSG_SIZ];
+ char *d, *s, buf[4*MSG_SIZ];
struct passwd *pwd;
s = path;
if (*s == '~') {
if (*(s+1) == '/') {
- strcpy(d, getpwuid(getuid())->pw_dir);
- strcat(d, s+1);
+ safeStrCpy(d, getpwuid(getuid())->pw_dir, 4*MSG_SIZ );
+ strcat(d, s+1);
}
else {
- strcpy(buf, s+1);
- *strchr(buf, '/') = 0;
- pwd = getpwnam(buf);
- if (!pwd)
- {
- fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
- buf, path);
- return NULL;
- }
- strcpy(d, pwd->pw_dir);
- strcat(d, strchr(s+1, '/'));
+ safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) );
+ *strchr(buf, '/') = 0;
+ pwd = getpwnam(buf);
+ if (!pwd)
+ {
+ fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
+ buf, path);
+ return NULL;
+ }
+ safeStrCpy(d, pwd->pw_dir, 4*MSG_SIZ );
+ strcat(d, strchr(s+1, '/'));
}
}
else
- strcpy(d, s);
+ safeStrCpy(d, s, 4*MSG_SIZ );
return static_buf;
}
Pixel foregroundOrWarningColor = timerForegroundPixel;
if (timer > 0 &&
- appData.lowTimeWarning &&
+ appData.lowTimeWarning &&
(timer / 1000) < appData.icsAlarmTime)
foregroundOrWarningColor = lowTimeWarningColor;
if (appData.clockMode) {
- sprintf(buf, "%s: %s", color, TimeString(timer));
- XtSetArg(args[0], XtNlabel, buf);
+ snprintf(buf, MSG_SIZ, "%s: %s", color, TimeString(timer));
+ XtSetArg(args[0], XtNlabel, buf);
} else {
- sprintf(buf, "%s ", color);
- XtSetArg(args[0], XtNlabel, buf);
+ snprintf(buf, MSG_SIZ, "%s ", color);
+ XtSetArg(args[0], XtNlabel, buf);
}
if (highlight) {
most simple-minded way possible.
*/
i = 0;
- strcpy(buf, cmdLine);
+ safeStrCpy(buf, cmdLine, sizeof(buf)/sizeof(buf[0]) );
p = buf;
for (;;) {
while(*p == ' ') p++;
}
q = is->buf;
while (p < is->unused) {
- *q++ = *p++;
+ *q++ = *p++;
}
is->unused = q;
} else {
- count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
- if (count == -1)
- error = errno;
- else
- error = 0;
- (is->func)(is, is->closure, is->buf, count, error);
+# if HAVE_LIBREADLINE
+ /* check if input is from stdin, if yes, use gnu-readline */
+ if( is->fd==fileno(stdin) )
+ {
+ /* to clear the line */
+ printf("\r \r");
+
+ /* read from stdin */
+ rl_callback_read_char();
+
+ /* redisplay the current line, check special case for login and password */
+ if(sending_ICS_password)
+ {
+ int i; char buf[MSG_SIZ];
+
+ bzero(buf,MSG_SIZ);
+
+ /* blank the password */
+ count = strlen(rl_line_buffer);
+ if(count>MSG_SIZ-1)
+ {
+ printf("PROBLEM with readline\n");
+ count=MSG_SIZ;
+ }
+ for(i=0;i<count;i++)
+ buf[i]='*';
+ i++;
+ buf[i]='\0';
+ printf("\rpassword: %s",buf);
+ }
+ else if (sending_ICS_login)
+ {
+ /* show login prompt */
+ count = strlen(rl_line_buffer);
+ printf("\rlogin: %s",rl_line_buffer);
+ }
+ else
+ rl_reset_line_state();
+
+ if(readline_complete)
+ {
+ /* copy into XBoards buffer */
+ count = strlen(readline_buffer);
+ if (count>INPUT_SOURCE_BUF_SIZE-1)
+ {
+ printf("PROBLEM with readline\n");
+ count = INPUT_SOURCE_BUF_SIZE;
+ };
+ strncpy(is->buf,readline_buffer,count);
+ is->buf[count]='\n';count++;
+
+ /* reset gnu-readline state */
+ free(readline_buffer);
+ readline_buffer=NULL;
+ readline_complete=0;
+
+ if (count == -1)
+ error = errno;
+ else
+ error = 0;
+ (is->func)(is, is->closure, is->buf, count, error);
+
+ /* are we done with the password? */
+ if(sending_ICS_password)
+ sending_ICS_password=0;
+ if(sending_ICS_login)
+ sending_ICS_login=0;
+ }
+ }
+ else
+ {
+ /* input not from stdin, use default method */
+ count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
+ if (count == -1)
+ error = errno;
+ else
+ error = 0;
+ (is->func)(is, is->closure, is->buf, count, error);
+ };
+#else /* no readline support */
+ count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
+ if (count == -1)
+ error = errno;
+ else
+ error = 0;
+ (is->func)(is, is->closure, is->buf, count, error);
+#endif
+
}
}
ChildProc *cp = (ChildProc *) pr;
int outCount;
+
if (pr == NoProc)
{
- if (appData.noJoin || !appData.useInternalWrap)
- outCount = fwrite(message, 1, count, stdout);
- else
+ if (appData.noJoin || !appData.useInternalWrap)
+ outCount = fwrite(message, 1, count, stdout);
+ else
{
- int width = get_term_width();
- int len = wrap(NULL, message, count, width, &line);
- char *msg = malloc(len);
- int dbgchk;
-
- if (!msg)
- outCount = fwrite(message, 1, count, stdout);
- else
+ int width = get_term_width();
+ int len = wrap(NULL, message, count, width, &line);
+ char *msg = malloc(len);
+ int dbgchk;
+
+ if (!msg)
+ outCount = fwrite(message, 1, count, stdout);
+ else
{
- dbgchk = wrap(msg, message, count, width, &line);
- if (dbgchk != len && appData.debugMode)
- fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len);
- outCount = fwrite(msg, 1, dbgchk, stdout);
- free(msg);
+ dbgchk = wrap(msg, message, count, width, &line);
+ if (dbgchk != len && appData.debugMode)
+ fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len);
+ outCount = fwrite(msg, 1, dbgchk, stdout);
+ free(msg);
}
}
+
+# if HAVE_LIBREADLINE
+ /* readline support */
+ if(strlen(rl_line_buffer))
+ printf("\n> %s",rl_line_buffer);
+#endif
+
}
else
outCount = write(cp->fdTo, message, count);
kind = 0;
else
kind = 2;
+ if(appData.upsideDown && flipView) kind ^= 2;
XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
dest, clip,
0, 0, squareSize, squareSize,
if (!appData.animate || appData.blindfold)
return;
- if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing ||
- board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing)
+ if(board[toY][toX] == WhiteRook && board[fromY][fromX] == WhiteKing ||
+ board[toY][toX] == BlackRook && board[fromY][fromX] == BlackKing)
return; // [HGM] FRC: no animtion of FRC castlings, as to-square is not true to-square
if (fromY < 0 || fromX < 0 || toX < 0 || toY < 0) return;
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>
return default_width;
}
-void update_ics_width()
+void
+update_ics_width()
{
- static int old_width = 0;
- int new_width = get_term_width();
+ static int old_width = 0;
+ int new_width = get_term_width();
- if (old_width != new_width)
- ics_printf("set width %d\n", new_width);
- old_width = new_width;
+ if (old_width != new_width)
+ ics_printf("set width %d\n", new_width);
+ old_width = new_width;
}
void NotifyFrontendLogin()
{
update_ics_width();
}
+
+# if HAVE_LIBREADLINE
+static void
+ReadlineCompleteHandler(char* ptr)
+{
+ /* make gnu-readline keep the history */
+ readline_buffer = ptr;
+ readline_complete = 1;
+
+ if (ptr && *ptr && !sending_ICS_password && !sending_ICS_login)
+ add_history(ptr);
+
+ return;
+}
+#endif