X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=8a86e26a57707a2fcf685cbfee2af55dfc8422c3;hb=fb6bfeeb1a191e561fa63e20bc5bff3666ca3898;hp=b66006a9c4a85b148e98684fe5e1b3f8b412747f;hpb=7ea58805958618de5217dc5d20e93e5d7bd05e96;p=xboard.git diff --git a/xboard.c b/xboard.c index b66006a..8a86e26 100644 --- a/xboard.c +++ b/xboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * The following terms apply to Digital Equipment Corporation's copyright * interest in XBoard: @@ -60,6 +60,7 @@ #include #include #include +#include #if !OMIT_SOCKETS # if HAVE_SYS_SOCKET_H @@ -241,7 +242,7 @@ FILE * XsraSelFile P((Widget w, char *prompt, char *ok, char *cancel, char *fail RETSIGTYPE CmailSigHandler P((int sig)); RETSIGTYPE IntSigHandler P((int sig)); RETSIGTYPE TermSizeSigHandler P((int sig)); -void CreateGCs P((void)); +void CreateGCs P((int redo)); void CreateXIMPieces P((void)); void CreateXPMPieces P((void)); void CreateXPMBoard P((char *s, int n)); @@ -391,28 +392,21 @@ void AnimateDraggingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AnimateMovingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutocommProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void AutoflipProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutobsProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void AutoraiseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FlashMovesProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void GetMoveListProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); void HighlightDraggingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void HighlightArrowProc P((Widget w, XEvent *event, String *prms, + Cardinal *nprms)); void MoveSoundProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void OldSaveStyleProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); +//void IcsAlarmProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void OneClickProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PeriodicUpdatesProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PonderNextMoveProc P((Widget w, XEvent *event, String *prms, @@ -421,8 +415,7 @@ void PopupMoveErrorsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void PopupExitMessageProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +//void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ShowCoordsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void ShowThinkingProc P((Widget w, XEvent *event, String *prms, @@ -461,6 +454,11 @@ void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopUp P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void IcsOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void SoundOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void BoardOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void LoadOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void SaveOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void GameListOptionsPopDown P(()); void ShufflePopDown P(()); void EnginePopDown P(()); @@ -471,6 +469,9 @@ void SettingsPopDown P(()); void update_ics_width P(()); int get_term_width P(()); int CopyMemoProc P(()); +void DrawArrowHighlight P((int fromX, int fromY, int toX,int toY)); +Boolean IsDrawArrowEnabled P(()); + /* * XBoard depends on Xt R4 or higher */ @@ -601,9 +602,9 @@ MenuItem fileMenu[] = { // {N_("Load Next Game"), "Load Next Game", LoadNextGameProc}, // {N_("Load Previous Game"), "Load Previous Game", LoadPrevGameProc}, // {N_("Reload Same Game"), "Reload Same Game", ReloadGameProc}, + {N_("Next Position Shift+PgDn"), "Load Next Position", LoadNextPositionProc}, + {N_("Prev Position Shift+PgUp"), "Load Previous Position", LoadPrevPositionProc}, {"----", NULL, NothingProc}, -// {N_("Load Next Position"), "Load Next Position", LoadNextPositionProc}, -// {N_("Load Previous Position"), "Load Previous Position", LoadPrevPositionProc}, // {N_("Reload Same Position"), "Reload Same Position", ReloadPositionProc}, {N_("Save Game Ctrl+S"), "Save Game", SaveGameProc}, {N_("Save Position Ctrl+Shift+S"), "Save Position", SavePositionProc}, @@ -649,6 +650,9 @@ MenuItem viewMenu[] = { {N_("Tags"), "Show Tags", EditTagsProc}, {N_("Comments"), "Show Comments", EditCommentProc}, {N_("ICS Input Box"), "ICS Input Box", IcsInputBoxProc}, + {"----", NULL, NothingProc}, + {N_("Board..."), "Board Options", BoardOptionsProc}, + {N_("Game List Tags..."), "Game List", GameListOptionsPopUp}, {NULL, NULL, NULL} }; @@ -704,33 +708,33 @@ MenuItem optionsMenu[] = { {N_("Time Control ... Alt+Shift+T"), "Time Control", TimeControlProc}, {N_("Common Engine ... Alt+Shift+U"), "Common Engine", UciMenuProc}, {N_("Adjudications ... Alt+Shift+J"), "Adjudications", EngineMenuProc}, + {N_("ICS ..."), "ICS", IcsOptionsProc}, + {N_("Load Game ..."), "Load Game", LoadOptionsProc}, + {N_("Save Game ..."), "Save Game", SaveOptionsProc}, +// {N_(" ..."), "", OptionsProc}, {N_("Game List ..."), "Game List", GameListOptionsPopUp}, + {N_("Sounds ..."), "Sounds", SoundOptionsProc}, {"----", NULL, NothingProc}, {N_("Always Queen Ctrl+Shift+Q"), "Always Queen", AlwaysQueenProc}, {N_("Animate Dragging"), "Animate Dragging", AnimateDraggingProc}, {N_("Animate Moving Ctrl+Shift+A"), "Animate Moving", AnimateMovingProc}, - {N_("Auto Comment"), "Auto Comment", AutocommProc}, {N_("Auto Flag Ctrl+Shift+F"), "Auto Flag", AutoflagProc}, {N_("Auto Flip View"), "Auto Flip View", AutoflipProc}, - {N_("Auto Observe"), "Auto Observe", AutobsProc}, - {N_("Auto Raise Board"), "Auto Raise Board", AutoraiseProc}, - {N_("Auto Save"), "Auto Save", AutosaveProc}, {N_("Blindfold"), "Blindfold", BlindfoldProc}, {N_("Flash Moves"), "Flash Moves", FlashMovesProc}, - {N_("Get Move List"), "Get Move List", GetMoveListProc}, #if HIGHDRAG {N_("Highlight Dragging"), "Highlight Dragging", HighlightDraggingProc}, #endif {N_("Highlight Last Move"), "Highlight Last Move", HighlightLastMoveProc}, + {N_("Highlight With Arrow"), "Arrow", HighlightArrowProc}, {N_("Move Sound"), "Move Sound", MoveSoundProc}, - {N_("ICS Alarm"), "ICS Alarm", IcsAlarmProc}, - {N_("Old Save Style"), "Old Save Style", OldSaveStyleProc}, +// {N_("ICS Alarm"), "ICS Alarm", IcsAlarmProc}, + {N_("One-Click Moving"), "OneClick", OneClickProc}, {N_("Periodic Updates"), "Periodic Updates", PeriodicUpdatesProc}, {N_("Ponder Next Move Ctrl+Shift+P"), "Ponder Next Move", PonderNextMoveProc}, {N_("Popup Exit Message"), "Popup Exit Message", PopupExitMessageProc}, {N_("Popup Move Errors"), "Popup Move Errors", PopupMoveErrorsProc}, - {N_("Premove"), "Premove", PremoveProc}, - {N_("Quiet Play"), "Quiet Play", QuietPlayProc}, +// {N_("Premove"), "Premove", PremoveProc}, {N_("Show Coords"), "Show Coords", ShowCoordsProc}, {N_("Hide Thinking Ctrl+Shift+H"), "Hide Thinking", HideThinkingProc}, {N_("Test Legality Ctrl+Shift+L"), "Test Legality", TestLegalityProc}, @@ -922,7 +926,6 @@ XtActionsRec boardActions[] = { { "ShowMoveListProc", HistoryShowProc}, { "EditTagsProc", EditCommentProc }, { "EditCommentProc", EditCommentProc }, - { "IcsAlarmProc", IcsAlarmProc }, { "IcsInputBoxProc", IcsInputBoxProc }, { "PauseProc", PauseProc }, { "AcceptProc", AcceptProc }, @@ -959,26 +962,20 @@ XtActionsRec boardActions[] = { { "AnimateMovingProc", AnimateMovingProc }, { "AutoflagProc", AutoflagProc }, { "AutoflipProc", AutoflipProc }, - { "AutobsProc", AutobsProc }, - { "AutoraiseProc", AutoraiseProc }, - { "AutosaveProc", AutosaveProc }, { "BlindfoldProc", BlindfoldProc }, { "FlashMovesProc", FlashMovesProc }, { "FlipViewProc", FlipViewProc }, - { "GetMoveListProc", GetMoveListProc }, #if HIGHDRAG { "HighlightDraggingProc", HighlightDraggingProc }, #endif { "HighlightLastMoveProc", HighlightLastMoveProc }, - { "IcsAlarmProc", IcsAlarmProc }, +// { "IcsAlarmProc", IcsAlarmProc }, { "MoveSoundProc", MoveSoundProc }, - { "OldSaveStyleProc", OldSaveStyleProc }, { "PeriodicUpdatesProc", PeriodicUpdatesProc }, { "PonderNextMoveProc", PonderNextMoveProc }, { "PopupExitMessageProc", PopupExitMessageProc }, { "PopupMoveErrorsProc", PopupMoveErrorsProc }, - { "PremoveProc", PremoveProc }, - { "QuietPlayProc", QuietPlayProc }, +// { "PremoveProc", PremoveProc }, { "ShowCoordsProc", ShowCoordsProc }, { "ShowThinkingProc", ShowThinkingProc }, { "HideThinkingProc", HideThinkingProc }, @@ -1027,8 +1024,8 @@ char globalTranslations[] = :Ctrlc: CopyGameProc() \n \ :Ctrlv: PasteGameProc() \n \ :CtrlO: LoadPositionProc() \n \ - :Shift MetaNext: LoadNextPositionProc() \n \ - :Shift MetaPrior: LoadPrevPositionProc() \n \ + :ShiftNext: LoadNextPositionProc() \n \ + :ShiftPrior: LoadPrevPositionProc() \n \ :CtrlS: SavePositionProc() \n \ :CtrlC: CopyPositionProc() \n \ :CtrlV: PastePositionProc() \n \ @@ -1475,7 +1472,7 @@ void SaveFontArg(FILE *f, ArgDescriptor *ad) { char *name; - int i, n = (int)ad->argLoc; + int i, n = (int)(intptr_t)ad->argLoc; switch(n) { case 0: // CLOCK_FONT name = appData.clockFont; @@ -1507,14 +1504,14 @@ ExportSounds() void SaveAttribsArg(FILE *f, ArgDescriptor *ad) { // here the "argLoc" defines a table index. It could have contained the 'ta' pointer itself, though - fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)ad->argLoc]); + fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, (&appData.colorShout)[(int)(intptr_t)ad->argLoc]); } void SaveColor(FILE *f, ArgDescriptor *ad) { // in WinBoard the color is an int and has to be converted to text. In X it would be a string already? - if(colorVariable[(int)ad->argLoc]) - fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)ad->argLoc]); + if(colorVariable[(int)(intptr_t)ad->argLoc]) + fprintf(f, OPTCHAR "%s" SEPCHAR "%s\n", ad->argName, *(char**)colorVariable[(int)(intptr_t)ad->argLoc]); } void @@ -1661,6 +1658,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags) XtSetArg(args[0], XtNdefaultDistance, &sep); XtGetValues(formWidget, args, 1); + if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; boardWidth = lineGap + BOARD_WIDTH * (squareSize + lineGap); boardHeight = lineGap + BOARD_HEIGHT * (squareSize + lineGap); CreateGrid(); @@ -1788,6 +1786,104 @@ void InitDrawingSizes(BoardSize boardSize, int flags) } #endif +void ParseIcsTextColors() +{ // [HGM] tken out of main(), so it can be called from ICS-Options dialog + if (parse_cpair(ColorShout, appData.colorShout) < 0 || + parse_cpair(ColorSShout, appData.colorSShout) < 0 || + parse_cpair(ColorChannel1, appData.colorChannel1) < 0 || + parse_cpair(ColorChannel, appData.colorChannel) < 0 || + parse_cpair(ColorKibitz, appData.colorKibitz) < 0 || + parse_cpair(ColorTell, appData.colorTell) < 0 || + parse_cpair(ColorChallenge, appData.colorChallenge) < 0 || + parse_cpair(ColorRequest, appData.colorRequest) < 0 || + parse_cpair(ColorSeek, appData.colorSeek) < 0 || + parse_cpair(ColorNormal, appData.colorNormal) < 0) + { + if (appData.colorize) { + fprintf(stderr, + _("%s: can't parse color names; disabling colorization\n"), + programName); + } + appData.colorize = FALSE; + } +} + +int MakeColors() +{ // [HGM] taken out of main(), so it can be called from BoardOptions dialog + XrmValue vFrom, vTo; + int forceMono = False; + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.lightSquareColor; + vFrom.size = strlen(appData.lightSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + lightSquareColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.darkSquareColor; + vFrom.size = strlen(appData.darkSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + darkSquareColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.whitePieceColor; + vFrom.size = strlen(appData.whitePieceColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + whitePieceColor = *(Pixel *) vTo.addr; + } + } + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.blackPieceColor; + vFrom.size = strlen(appData.blackPieceColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + blackPieceColor = *(Pixel *) vTo.addr; + } + } + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.highlightSquareColor; + vFrom.size = strlen(appData.highlightSquareColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + highlightSquareColor = *(Pixel *) vTo.addr; + } + } + + if (!appData.monoMode) { + vFrom.addr = (caddr_t) appData.premoveHighlightColor; + vFrom.size = strlen(appData.premoveHighlightColor); + XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); + if (vTo.addr == NULL) { + appData.monoMode = True; + forceMono = True; + } else { + premoveHighlightColor = *(Pixel *) vTo.addr; + } + } + return forceMono; +} + int main(argc, argv) int argc; @@ -2022,74 +2118,7 @@ XBoard square size (hint): %d\n\ appData.monoMode = True; } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.lightSquareColor; - vFrom.size = strlen(appData.lightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - lightSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.darkSquareColor; - vFrom.size = strlen(appData.darkSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - darkSquareColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.whitePieceColor; - vFrom.size = strlen(appData.whitePieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - whitePieceColor = *(Pixel *) vTo.addr; - } - } - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.blackPieceColor; - vFrom.size = strlen(appData.blackPieceColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - blackPieceColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.highlightSquareColor; - vFrom.size = strlen(appData.highlightSquareColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - highlightSquareColor = *(Pixel *) vTo.addr; - } - } - - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.premoveHighlightColor; - vFrom.size = strlen(appData.premoveHighlightColor); - XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); - if (vTo.addr == NULL) { - appData.monoMode = True; - forceMono = True; - } else { - premoveHighlightColor = *(Pixel *) vTo.addr; - } - } + forceMono = MakeColors(); if (forceMono) { fprintf(stderr, _("%s: too few colors available; trying monochrome mode\n"), @@ -2116,24 +2145,7 @@ XBoard square size (hint): %d\n\ (unsigned long) XBlackPixel(xDisplay, xScreen)); } - if (parse_cpair(ColorShout, appData.colorShout) < 0 || - parse_cpair(ColorSShout, appData.colorSShout) < 0 || - parse_cpair(ColorChannel1, appData.colorChannel1) < 0 || - parse_cpair(ColorChannel, appData.colorChannel) < 0 || - parse_cpair(ColorKibitz, appData.colorKibitz) < 0 || - parse_cpair(ColorTell, appData.colorTell) < 0 || - parse_cpair(ColorChallenge, appData.colorChallenge) < 0 || - parse_cpair(ColorRequest, appData.colorRequest) < 0 || - parse_cpair(ColorSeek, appData.colorSeek) < 0 || - parse_cpair(ColorNormal, appData.colorNormal) < 0) - { - if (appData.colorize) { - fprintf(stderr, - _("%s: can't parse color names; disabling colorization\n"), - programName); - } - appData.colorize = FALSE; - } + ParseIcsTextColors(); textColors[ColorNone].fg = textColors[ColorNone].bg = -1; textColors[ColorNone].attr = 0; @@ -2404,10 +2416,6 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), args, 1); } - if (appData.autoComment) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"), - args, 1); - } if (appData.autoCallFlag) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"), args, 1); @@ -2416,26 +2424,6 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"), args, 1); } - if (appData.autoObserve) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"), - args, 1); - } - if (appData.autoRaiseBoard) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Auto Raise Board"), args, 1); - } - if (appData.autoSaveGames) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); - } - if (appData.saveGameFile[0] != NULLCHAR) { - /* Can't turn this off from menu */ - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); - XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - False); - - } if (appData.blindfold) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"), args, 1); @@ -2445,10 +2433,6 @@ XBoard square size (hint): %d\n\ "menuOptions.Flash Moves"), args, 1); } - if (appData.getMoveList) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"), - args, 1); - } #if HIGHDRAG if (appData.highlightDragging) { XtSetValues(XtNameToWidget(menuBarWidget, @@ -2461,17 +2445,22 @@ XBoard square size (hint): %d\n\ "menuOptions.Highlight Last Move"), args, 1); } - if (appData.icsAlarm) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), + if (appData.highlightMoveWithArrow) { + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Arrow"), args, 1); } +// if (appData.icsAlarm) { +// XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), +// args, 1); +// } if (appData.ringBellAfterMoves) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"), args, 1); } - if (appData.oldSaveStyle) { + if (appData.oneClick) { XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Old Save Style"), args, 1); + "menuOptions.OneClick"), args, 1); } if (appData.periodicUpdates) { XtSetValues(XtNameToWidget(menuBarWidget, @@ -2489,14 +2478,10 @@ XBoard square size (hint): %d\n\ XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"), args, 1); } - if (appData.premove) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Premove"), args, 1); - } - if (appData.quietPlay) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Quiet Play"), args, 1); - } +// if (appData.premove) { +// XtSetValues(XtNameToWidget(menuBarWidget, +// "menuOptions.Premove"), args, 1); +// } if (appData.showCoords) { XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"), args, 1); @@ -2547,7 +2532,7 @@ XBoard square size (hint): %d\n\ CatchDeleteWindow(shellWidget, "QuitProc"); - CreateGCs(); + CreateGCs(False); CreateGrid(); #if HAVE_LIBXPM if (appData.bitmapDirectory[0] != NULLCHAR) { @@ -2799,15 +2784,11 @@ Enables ncpEnables[] = { { "menuEngine.Engine #2 Settings", False }, { "menuEngine.Move Now", False }, { "menuEngine.Retract Move", False }, - { "menuOptions.Auto Comment", False }, { "menuOptions.Auto Flag", False }, { "menuOptions.Auto Flip View", False }, - { "menuOptions.Auto Observe", False }, - { "menuOptions.Auto Raise Board", False }, - { "menuOptions.Get Move List", False }, - { "menuOptions.ICS Alarm", False }, + { "menuOptions.ICS", False }, +// { "menuOptions.ICS Alarm", False }, { "menuOptions.Move Sound", False }, - { "menuOptions.Quiet Play", False }, { "menuOptions.Hide Thinking", False }, { "menuOptions.Periodic Updates", False }, { "menuOptions.Ponder Next Move", False }, @@ -2828,12 +2809,7 @@ Enables gnuEnables[] = { { "menuAction.Upload to Examine", False }, { "menuEdit.Revert", False }, { "menuEdit.Annotate", False }, - { "menuOptions.Auto Comment", False }, - { "menuOptions.Auto Observe", False }, - { "menuOptions.Auto Raise Board", False }, - { "menuOptions.Get Move List", False }, - { "menuOptions.Premove", False }, - { "menuOptions.Quiet Play", False }, + { "menuOptions.ICS", False }, /* The next two options rely on SetCmailMode being called *after* */ /* SetGNUMode so that when GNU is being used to give hints these */ @@ -3136,7 +3112,31 @@ FindFont(pattern, targetPxlSize) return p; } -void CreateGCs() +void DeleteGCs() +{ // [HGM] deletes GCs that are to be remade, to prevent resource leak; + // must be called before all non-first callse to CreateGCs() + XtReleaseGC(shellWidget, highlineGC); + XtReleaseGC(shellWidget, lightSquareGC); + XtReleaseGC(shellWidget, darkSquareGC); + if (appData.monoMode) { + if (DefaultDepth(xDisplay, xScreen) == 1) { + XtReleaseGC(shellWidget, wbPieceGC); + } else { + XtReleaseGC(shellWidget, bwPieceGC); + } + } else { + XtReleaseGC(shellWidget, prelineGC); + XtReleaseGC(shellWidget, jailSquareGC); + XtReleaseGC(shellWidget, wdPieceGC); + XtReleaseGC(shellWidget, wlPieceGC); + XtReleaseGC(shellWidget, wjPieceGC); + XtReleaseGC(shellWidget, bdPieceGC); + XtReleaseGC(shellWidget, blPieceGC); + XtReleaseGC(shellWidget, bjPieceGC); + } +} + +void CreateGCs(int redo) { XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground | GCBackground | GCFunction | GCPlaneMask; @@ -3148,6 +3148,9 @@ void CreateGCs() gc_values.line_style = LineSolid; gc_values.function = GXcopy; + if(redo) { + DeleteGCs(); // called a second time; clean up old GCs first + } else { // [HGM] grid and font GCs created on first call only gc_values.foreground = XBlackPixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); lineGC = XtGetGC(shellWidget, value_mask, &gc_values); @@ -3157,12 +3160,12 @@ void CreateGCs() coordGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, coordGC, coordFontID); - // [HGM] make font for holdings counts (white on black0 + // [HGM] make font for holdings counts (white on black) gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XBlackPixel(xDisplay, xScreen); countGC = XtGetGC(shellWidget, value_mask, &gc_values); XSetFont(xDisplay, countGC, countFontID); - + } if (appData.monoMode) { gc_values.foreground = XWhitePixel(xDisplay, xScreen); gc_values.background = XWhitePixel(xDisplay, xScreen); @@ -3289,6 +3292,8 @@ void loadXIM(xim, xmask, filename, dest, mask) } } + fclose(fp); + /* create Pixmap of piece */ *dest = XCreatePixmap(xDisplay, DefaultRootWindow(xDisplay), w, h, xim->depth); @@ -3414,12 +3419,24 @@ void CreateXPMBoard(char *s, int kind) { XpmAttributes attr; attr.valuemask = 0; - if(s == NULL || *s == 0 || *s == '*') return; + if(s == NULL || *s == 0 || *s == '*') { useTexture &= ~(kind+1); return; } if (XpmReadFileToPixmap(xDisplay, xBoardWindow, s, &(xpmBoardBitmap[kind]), NULL, &attr) == 0) { useTexture |= kind + 1; textureW[kind] = attr.width; textureH[kind] = attr.height; } } +void FreeXPMPieces() +{ // [HGM] to prevent resoucre leak on calling CreaeXPMPieces() a second time, + // thisroutine has to be called t free the old piece pixmaps + int piece, kind; + for (piece = (int) WhitePawn; piece <= (int) WhiteKing + 4; piece++) + for (kind=0; kind<4; kind++) XFreePixmap(xDisplay, xpmPieceBitmap2[kind][piece]); + if(useImageSqs) { + XFreePixmap(xDisplay, xpmLightSquare); + XFreePixmap(xDisplay, xpmDarkSquare); + } +} + void CreateXPMPieces() { int piece, kind, r; @@ -3428,6 +3445,9 @@ void CreateXPMPieces() XpmAttributes attr; static char *xpmkind[] = { "ll", "ld", "dl", "dd" }; XpmColorSymbol symbols[4]; + static int redo = False; + + if(redo) FreeXPMPieces(); else redo = 1; /* The XSynchronize calls were copied from CreatePieces. Not sure if needed, but can't hurt */ @@ -3945,11 +3965,7 @@ void WhiteClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (gameMode == EditPosition || gameMode == IcsExamining) { - SetWhiteToPlayEvent(); - } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } + ClockClick(0); } void BlackClock(w, event, prms, nprms) @@ -3958,11 +3974,7 @@ void BlackClock(w, event, prms, nprms) String *prms; Cardinal *nprms; { - if (gameMode == EditPosition || gameMode == IcsExamining) { - SetBlackToPlayEvent(); - } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } + ClockClick(1); } @@ -4259,7 +4271,7 @@ static void colorDrawPieceImage(piece, square_color, x, y, dest) } break; } - if(appData.upsideDown && flipView) kind ^= 2; // swap white and black pieces + if(appData.upsideDown && flipView) { kind ^= 2; p += p < BlackPawn ? BlackPawn : -BlackPawn; }// swap white and black pieces if(useTexture & square_color+1) { BlankSquare(x, y, square_color, piece, dest, 1); // erase previous contents with background XSetClipMask(xDisplay, wlPieceGC, xpmMask[p]); @@ -4603,6 +4615,10 @@ void XDrawPosition(w, repaint, board) if (!repaint && lastBoardValid[nr] && (nr == 1 || lastFlipView == flipView)) { + if ( lineGap && IsDrawArrowEnabled()) + XDrawSegments(xDisplay, xBoardWindow, lineGC, + gridSegments, BOARD_HEIGHT + BOARD_WIDTH + 2); + /* If too much changes (begin observing new game, etc.), don't do flashing */ do_flash = too_many_diffs(board, lastBoard[nr]) ? 0 : 1; @@ -4665,6 +4681,7 @@ void XDrawPosition(w, repaint, board) if (hi2X >= 0 && hi2Y >= 0) { drawHighlight(hi2X, hi2Y, highlineGC); } + DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y); } /* If piece being dragged around board, must redraw that too */ DrawDragPiece(); @@ -4976,9 +4993,9 @@ Widget MiscCreate(name, text, mutable, callback, lines) XTranslateCoordinates(xDisplay, XtWindow(shellWidget), RootWindowOfScreen(XtScreen(shellWidget)), (bw_width - w) / 2, 0 - h / 2, &xx, &yy, &junk); -#endif /*!NOTDEF*/ x = xx; y = yy; +#endif /*!NOTDEF*/ if (y < 0) y = 0; /*avoid positioning top offscreen*/ j = 0; @@ -5357,6 +5374,16 @@ void PromotionPopUp() layout, args, j); if(gameInfo.variant != VariantShogi) { + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) { + XawDialogAddButton(dialog, _("Warlord"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("General"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("Lieutenant"), PromotionCallback, + (XtPointer) dialog); + XawDialogAddButton(dialog, _("Captain"), PromotionCallback, + (XtPointer) dialog); + } else { XawDialogAddButton(dialog, _("Queen"), PromotionCallback, (XtPointer) dialog); XawDialogAddButton(dialog, _("Rook"), PromotionCallback, @@ -5365,7 +5392,9 @@ void PromotionPopUp() (XtPointer) dialog); XawDialogAddButton(dialog, _("Knight"), PromotionCallback, (XtPointer) dialog); + } if (!appData.testLegality || gameInfo.variant == VariantSuicide || + gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || gameInfo.variant == VariantGiveaway) { XawDialogAddButton(dialog, _("King"), PromotionCallback, (XtPointer) dialog); @@ -5929,6 +5958,7 @@ SendGameSelection(Widget w, Atom *selection, Atom *target, rewind(f); selection_tmp = XtMalloc(len + 1); count = fread(selection_tmp, 1, len, f); + fclose(f); if (len != count) { XtFree(selection_tmp); return False; @@ -6536,26 +6566,6 @@ void AnimateMovingProc(w, event, prms, nprms) args, 1); } -void AutocommProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoComment = !appData.autoComment; - - if (appData.autoComment) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"), - args, 1); -} - - void AutoflagProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6594,63 +6604,6 @@ void AutoflipProc(w, event, prms, nprms) args, 1); } -void AutobsProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoObserve = !appData.autoObserve; - - if (appData.autoObserve) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"), - args, 1); -} - -void AutoraiseProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoRaiseBoard = !appData.autoRaiseBoard; - - if (appData.autoRaiseBoard) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Raise Board"), - args, 1); -} - -void AutosaveProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.autoSaveGames = !appData.autoSaveGames; - - if (appData.autoSaveGames) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"), - args, 1); -} - void BlindfoldProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6725,7 +6678,8 @@ void FlipViewProc(w, event, prms, nprms) DrawPosition(True, NULL); } -void GetMoveListProc(w, event, prms, nprms) +#if HIGHDRAG +void HighlightDraggingProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6733,20 +6687,19 @@ void GetMoveListProc(w, event, prms, nprms) { Arg args[16]; - appData.getMoveList = !appData.getMoveList; + appData.highlightDragging = !appData.highlightDragging; - if (appData.getMoveList) { + if (appData.highlightDragging) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - GetMoveListEvent(); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"), - args, 1); + XtSetValues(XtNameToWidget(menuBarWidget, + "menuOptions.Highlight Dragging"), args, 1); } +#endif -#if HIGHDRAG -void HighlightDraggingProc(w, event, prms, nprms) +void HighlightLastMoveProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6754,19 +6707,18 @@ void HighlightDraggingProc(w, event, prms, nprms) { Arg args[16]; - appData.highlightDragging = !appData.highlightDragging; + appData.highlightLastMove = !appData.highlightLastMove; - if (appData.highlightDragging) { + if (appData.highlightLastMove) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Dragging"), args, 1); + "menuOptions.Highlight Last Move"), args, 1); } -#endif -void HighlightLastMoveProc(w, event, prms, nprms) +void HighlightArrowProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6774,17 +6726,18 @@ void HighlightLastMoveProc(w, event, prms, nprms) { Arg args[16]; - appData.highlightLastMove = !appData.highlightLastMove; + appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow; - if (appData.highlightLastMove) { + if (appData.highlightMoveWithArrow) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Last Move"), args, 1); + "menuOptions.Arrow"), args, 1); } +#if 0 void IcsAlarmProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6803,6 +6756,7 @@ void IcsAlarmProc(w, event, prms, nprms) XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.ICS Alarm"), args, 1); } +#endif void MoveSoundProc(w, event, prms, nprms) Widget w; @@ -6823,8 +6777,7 @@ void MoveSoundProc(w, event, prms, nprms) args, 1); } - -void OldSaveStyleProc(w, event, prms, nprms) +void OneClickProc(w, event, prms, nprms) Widget w; XEvent *event; String *prms; @@ -6832,14 +6785,14 @@ void OldSaveStyleProc(w, event, prms, nprms) { Arg args[16]; - appData.oldSaveStyle = !appData.oldSaveStyle; + appData.oneClick = !appData.oneClick; - if (appData.oldSaveStyle) { + if (appData.oneClick) { XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); } else { XtSetArg(args[0], XtNleftBitmap, None); } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"), + XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.OneClick"), args, 1); } @@ -6919,6 +6872,7 @@ void PopupMoveErrorsProc(w, event, prms, nprms) args, 1); } +#if 0 void PremoveProc(w, event, prms, nprms) Widget w; XEvent *event; @@ -6937,25 +6891,7 @@ void PremoveProc(w, event, prms, nprms) XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Premove"), args, 1); } - -void QuietPlayProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; -{ - Arg args[16]; - - appData.quietPlay = !appData.quietPlay; - - if (appData.quietPlay) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"), - args, 1); -} +#endif void ShowCoordsProc(w, event, prms, nprms) Widget w; @@ -7468,7 +7404,9 @@ PlaySound(name) putc(BELLCHAR, stderr); } else { char buf[2048]; - snprintf(buf, sizeof(buf), "%s '%s' &", appData.soundProgram, name); + char *prefix = "", *sep = ""; + if(!strchr(name, '/')) { prefix = appData.soundDirectory; sep = "/"; } + snprintf(buf, sizeof(buf), "%s '%s%s%s' &", appData.soundProgram, prefix, sep, name); system(buf); } } @@ -8729,6 +8667,7 @@ BeginAnimation(anim, piece, startColor, start) { Pixmap mask; + if(appData.upsideDown && flipView) piece += piece < BlackPawn ? BlackPawn : -BlackPawn; /* The old buffer is initialised with the start square (empty) */ BlankSquare(start->x, start->y, startColor, EmptySquare, anim->saveBuf, 0); anim->prevFrame = *start; @@ -9093,3 +9032,196 @@ void NotifyFrontendLogin() { update_ics_width(); } + +/* [AS] Arrow highlighting support */ + +static double A_WIDTH = 5; /* Width of arrow body */ + +#define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */ +#define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */ + +static double Sqr( double x ) +{ + return x*x; +} + +static int Round( double x ) +{ + return (int) (x + 0.5); +} + +void SquareToPos(int rank, int file, int *x, int *y) +{ + if (flipView) { + *x = lineGap + ((BOARD_WIDTH-1)-file) * (squareSize + lineGap); + *y = lineGap + rank * (squareSize + lineGap); + } else { + *x = lineGap + file * (squareSize + lineGap); + *y = lineGap + ((BOARD_HEIGHT-1)-rank) * (squareSize + lineGap); + } +} + +/* Draw an arrow between two points using current settings */ +void DrawArrowBetweenPoints( int s_x, int s_y, int d_x, int d_y ) +{ + XPoint arrow[7]; + double dx, dy, j, k, x, y; + + if( d_x == s_x ) { + int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; + + arrow[0].x = s_x + A_WIDTH + 0.5; + arrow[0].y = s_y; + + arrow[1].x = s_x + A_WIDTH + 0.5; + arrow[1].y = d_y - h; + + arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[2].y = d_y - h; + + arrow[3].x = d_x; + arrow[3].y = d_y; + + arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5; + arrow[5].y = d_y - h; + + arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[4].y = d_y - h; + + arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5; + arrow[6].y = s_y; + } + else if( d_y == s_y ) { + int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; + + arrow[0].x = s_x; + arrow[0].y = s_y + A_WIDTH + 0.5; + + arrow[1].x = d_x - w; + arrow[1].y = s_y + A_WIDTH + 0.5; + + arrow[2].x = d_x - w; + arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + + arrow[3].x = d_x; + arrow[3].y = d_y; + + arrow[5].x = d_x - w; + arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5; + + arrow[4].x = d_x - w; + arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + + arrow[6].x = s_x; + arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5; + } + else { + /* [AS] Needed a lot of paper for this! :-) */ + dy = (double) (d_y - s_y) / (double) (d_x - s_x); + dx = (double) (s_x - d_x) / (double) (s_y - d_y); + + j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) ); + + k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) ); + + x = s_x; + y = s_y; + + arrow[0].x = Round(x - j); + arrow[0].y = Round(y + j*dx); + + arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice + arrow[1].y = Round(arrow[0].y - 2*j*dx); + + if( d_x > s_x ) { + x = (double) d_x - k; + y = (double) d_y - k*dy; + } + else { + x = (double) d_x + k; + y = (double) d_y + k*dy; + } + + x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends + + arrow[6].x = Round(x - j); + arrow[6].y = Round(y + j*dx); + + arrow[2].x = Round(arrow[6].x + 2*j); + arrow[2].y = Round(arrow[6].y - 2*j*dx); + + arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1)); + arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx); + + arrow[4].x = d_x; + arrow[4].y = d_y; + + arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1)); + arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx); + } + + XFillPolygon(xDisplay, xBoardWindow, highlineGC, arrow, 7, Nonconvex, CoordModeOrigin); +// Polygon( hdc, arrow, 7 ); +} + +/* [AS] Draw an arrow between two squares */ +void DrawArrowBetweenSquares( int s_col, int s_row, int d_col, int d_row ) +{ + int s_x, s_y, d_x, d_y, hor, vert, i; + + if( s_col == d_col && s_row == d_row ) { + return; + } + + /* Get source and destination points */ + SquareToPos( s_row, s_col, &s_x, &s_y); + SquareToPos( d_row, d_col, &d_x, &d_y); + + if( d_y > s_y ) { + d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides! + } + else if( d_y < s_y ) { + d_y += squareSize / 2 + squareSize / 4; + } + else { + d_y += squareSize / 2; + } + + if( d_x > s_x ) { + d_x += squareSize / 2 - squareSize / 4; + } + else if( d_x < s_x ) { + d_x += squareSize / 2 + squareSize / 4; + } + else { + d_x += squareSize / 2; + } + + s_x += squareSize / 2; + s_y += squareSize / 2; + + /* Adjust width */ + A_WIDTH = squareSize / 14.; //[HGM] make float + + DrawArrowBetweenPoints( s_x, s_y, d_x, d_y ); + + hor = 64*s_col + 32; vert = 64*s_row + 32; + for(i=0; i<= 64; i++) { + damage[0][vert+6>>6][hor+6>>6] = True; + damage[0][vert-6>>6][hor+6>>6] = True; + damage[0][vert+6>>6][hor-6>>6] = True; + damage[0][vert-6>>6][hor-6>>6] = True; + hor += d_col - s_col; vert += d_row - s_row; + } +} + +Boolean IsDrawArrowEnabled() +{ + return appData.highlightMoveWithArrow && squareSize >= 32; +} + +void DrawArrowHighlight(int fromX, int fromY, int toX,int toY) +{ + if( IsDrawArrowEnabled() && fromX >= 0 && fromY >= 0 && toX >= 0 && toY >= 0) + DrawArrowBetweenSquares(fromX, fromY, toX, toY); +}