X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=xboard.c;h=934f903d81fb4040c5ce59639635c986700eee6a;hb=b9c6b5e9fcd6321336ec28f25833530db79b928d;hp=f05027d92abf4cc18fb09a348d07ab5199590bf0;hpb=23912238e869ea3b134b7806456e0cfa4a363913;p=xboard.git diff --git a/xboard.c b/xboard.c index f05027d..934f903 100644 --- a/xboard.c +++ b/xboard.c @@ -203,15 +203,10 @@ extern char *getenv(); #include "xgamelist.h" #include "xhistory.h" #include "xedittags.h" +#include "menus.h" +#include "board.h" #include "gettext.h" -// must be moved to xengineoutput.h - -void EngineOutputProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void EvalGraphProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); - #ifdef __EMX__ #ifndef HAVE_USLEEP @@ -228,20 +223,6 @@ void EvalGraphProc P((Widget w, XEvent *event, # define N_(s) s #endif -typedef struct { - String string; - String ref; - XtActionProc proc; -} MenuItem; - -typedef struct { - String name; - String ref; - MenuItem *mi; - int textWidth; - Widget subMenu; -} 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 *filter, char *mode, int (*show_entry)(), char **name_return)); @@ -271,8 +252,8 @@ void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[], u_int wreq, u_int hreq)); void CreateGrid P((void)); int EventToSquare P((int x, int limit)); -void DrawSquare P((int row, int column, ChessSquare piece, int do_flash)); void EventProc P((Widget widget, caddr_t unused, XEvent *event)); +void DelayedDrag P((void)); void MoveTypeInProc P((Widget widget, caddr_t unused, XEvent *event)); void HandleUserMove P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); @@ -314,169 +295,22 @@ void PromotionPopDown P((void)); void PromotionCallback P((Widget w, XtPointer client_data, XtPointer call_data)); void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data)); -void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void LoadNextGameProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void LoadPrevGameProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void ReloadGameProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void LoadPositionProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void LoadNextPositionProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void LoadPrevPositionProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void ReloadPositionProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void CopyPositionProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void PastePositionProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void CopyGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void CopyGameListProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void PasteGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void SavePositionProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void MachineBlackProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void MachineWhiteProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void AnalyzeModeProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void AnalyzeFileProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void TwoMachinesProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void MatchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void MatchOptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void IcsClientProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void EditPositionProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void TrainingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void EditCommentProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void IcsInputBoxProc P((Widget w, XEvent *event, - String *prms, Cardinal *nprms)); -void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void RematchProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AdjuWhiteProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AdjuBlackProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AdjuDrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void KeyBindingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void QuitWrapper P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TypeInProc 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 TempBackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void TempForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); Boolean TempBackwardActive = False; -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, - Cardinal *nprms)); -void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AlwaysQueenProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void AnimateDraggingProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void AnimateMovingProc 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 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 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 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, - Cardinal *nprms)); -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 ShowCoordsProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void ShowThinkingProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void HideThinkingProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void TestLegalityProc P((Widget w, XEvent *event, String *prms, - Cardinal *nprms)); -void SaveSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void SaveOnExitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void InfoProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void ManProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); +void ManInner P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void DisplayMove P((int moveNumber)); void DisplayTitle P((char *title)); void ICSInitScript P((void)); -int LoadGamePopUp P((FILE *f, int gameNumber, char *title)); void ErrorPopUp P((char *title, char *text, int modal)); void ErrorPopDown P((void)); static char *ExpandPathName P((char *path)); -static void CreateAnimVars P((void)); -static void DragPieceMove P((int x, int y)); -static void DrawDragPiece P((void)); -char *ModeToWidgetName P((GameMode mode)); -void ShuffleMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void OptionsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void IcsTextProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); -void LoadEngineProc 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 EditBookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms)); void SelectMove P((Widget w, XEvent * event, String * params, Cardinal * nParams)); void GameListOptionsPopDown P(()); void GenericPopDown P(()); @@ -507,7 +341,6 @@ Widget shellWidget, layoutWidget, formWidget, boardWidget, messageWidget, 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]; @@ -534,19 +367,17 @@ BoardSize boardSize; Boolean chessProgram; int minX, minY; // [HGM] placement: volatile limits on upper-left corner -int squareSize, smallLayout = 0, tinyLayout = 0, +int smallLayout = 0, tinyLayout = 0, marginW, marginH, // [HGM] for run-time resizing fromX = -1, fromY = -1, toX, toY, commentUp = False, analysisUp = False, ICSInputBoxUp = False, askQuestionUp = False, filenameUp = False, promotionUp = False, pmFromX = -1, pmFromY = -1, - errorUp = False, errorExitStatus = -1, lineGap, defaultLineGap; + errorUp = False, errorExitStatus = -1, defaultLineGap; +Dimension textHeight; Pixel timerForegroundPixel, timerBackgroundPixel; Pixel buttonForegroundPixel, buttonBackgroundPixel; -char *chessDir, *programName, *programVersion, - *gameCopyFilename, *gamePasteFilename; +char *chessDir, *programName, *programVersion; Boolean alwaysOnTop = False; -Boolean saveSettingsOnExit; -char *settingsFileName; char *icsTextMenuString; char *icsNames; char *firstChessProgramNames; @@ -584,26 +415,6 @@ XImage *xim_Cross; #define White(piece) ((int)(piece) < (int)BlackPawn) -/* Variables for doing smooth animation. This whole thing - would be much easier if the board was double-buffered, - but that would require a fairly major rewrite. */ - -typedef struct { - Pixmap saveBuf; - Pixmap newBuf; - GC blitGC, pieceGC, outlineGC; - XPoint startSquare, prevFrame, mouseDelta; - int startColor; - int dragPiece; - Boolean dragActive; - int startBoardX, startBoardY; - } AnimState; - -/* There can be two pieces being animated at once: a player - can begin dragging a piece before the remote opponent has moved. */ - -static AnimState game, player; - /* Bitmaps for use as masks when drawing XPM pieces. Need one for each black and white piece. */ static Pixmap xpmMask[BlackKing + 1]; @@ -615,198 +426,13 @@ static Pixmap xpmMask[BlackKing + 1]; SizeDefaults sizeDefaults[] = SIZE_DEFAULTS; -MenuItem fileMenu[] = { - {N_("New Game Ctrl+N"), "New Game", ResetProc}, - {N_("New Shuffle Game ..."), "New Shuffle Game", ShuffleMenuProc}, - {N_("New Variant ... Alt+Shift+V"), "New Variant", NewVariantProc}, // [HGM] variant: not functional yet - {"----", NULL, NothingProc}, - {N_("Load Game Ctrl+O"), "Load Game", LoadGameProc}, - {N_("Load Position Ctrl+Shift+O"), "Load Position", LoadPositionProc}, -// {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_("Reload Same Position"), "Reload Same Position", ReloadPositionProc}, - {N_("Save Game Ctrl+S"), "Save Game", SaveGameProc}, - {N_("Save Position Ctrl+Shift+S"), "Save Position", SavePositionProc}, - {"----", NULL, NothingProc}, - {N_("Mail Move"), "Mail Move", MailMoveProc}, - {N_("Reload CMail Message"), "Reload CMail Message", ReloadCmailMsgProc}, - {"----", NULL, NothingProc}, - {N_("Quit Ctr+Q"), "Exit", QuitProc}, - {NULL, NULL, NULL} -}; - -MenuItem editMenu[] = { - {N_("Copy Game Ctrl+C"), "Copy Game", CopyGameProc}, - {N_("Copy Position Ctrl+Shift+C"), "Copy Position", CopyPositionProc}, - {N_("Copy Game List"), "Copy Game List", CopyGameListProc}, - {"----", NULL, NothingProc}, - {N_("Paste Game Ctrl+V"), "Paste Game", PasteGameProc}, - {N_("Paste Position Ctrl+Shift+V"), "Paste Position", PastePositionProc}, - {"----", NULL, NothingProc}, - {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc}, - {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, - {N_("Edit Tags"), "Edit Tags", EditTagsProc}, - {N_("Edit Comment"), "Edit Comment", EditCommentProc}, - {N_("Edit Book"), "Edit Book", EditBookProc}, - {"----", NULL, NothingProc}, - {N_("Revert Home"), "Revert", RevertProc}, - {N_("Annotate"), "Annotate", AnnotateProc}, - {N_("Truncate Game End"), "Truncate Game", TruncateGameProc}, - {"----", NULL, NothingProc}, - {N_("Backward Alt+Left"), "Backward", BackwardProc}, - {N_("Forward Alt+Right"), "Forward", ForwardProc}, - {N_("Back to Start Alt+Home"), "Back to Start", ToStartProc}, - {N_("Forward to End Alt+End"), "Forward to End", ToEndProc}, - {NULL, NULL, NULL} -}; - -MenuItem viewMenu[] = { - {N_("Flip View F2"), "Flip View", FlipViewProc}, - {"----", NULL, NothingProc}, - {N_("Engine Output Alt+Shift+O"), "Show Engine Output", EngineOutputProc}, - {N_("Move History Alt+Shift+H"), "Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code - {N_("Evaluation Graph Alt+Shift+E"), "Show Evaluation Graph", EvalGraphProc}, - {N_("Game List Alt+Shift+G"), "Show Game List", ShowGameListProc}, - {N_("ICS text menu"), "ICStex", IcsTextProc}, - {"----", NULL, NothingProc}, - {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} -}; - -MenuItem modeMenu[] = { - {N_("Machine White Ctrl+W"), "Machine White", MachineWhiteProc}, - {N_("Machine Black Ctrl+B"), "Machine Black", MachineBlackProc}, - {N_("Two Machines Ctrl+T"), "Two Machines", TwoMachinesProc}, - {N_("Analysis Mode Ctrl+A"), "Analysis Mode", AnalyzeModeProc}, - {N_("Analyze Game Ctrl+G"), "Analyze File", AnalyzeFileProc }, - {N_("Edit Game Ctrl+E"), "Edit Game", EditGameProc}, - {N_("Edit Position Ctrl+Shift+E"), "Edit Position", EditPositionProc}, - {N_("Training"), "Training", TrainingProc}, - {N_("ICS Client"), "ICS Client", IcsClientProc}, - {"----", NULL, NothingProc}, - {N_("Machine Match"), "Machine Match", MatchProc}, - {N_("Pause Pause"), "Pause", PauseProc}, - {NULL, NULL, NULL} -}; - -MenuItem actionMenu[] = { - {N_("Accept F3"), "Accept", AcceptProc}, - {N_("Decline F4"), "Decline", DeclineProc}, - {N_("Rematch F12"), "Rematch", RematchProc}, - {"----", NULL, NothingProc}, - {N_("Call Flag F5"), "Call Flag", CallFlagProc}, - {N_("Draw F6"), "Draw", DrawProc}, - {N_("Adjourn F7"), "Adjourn", AdjournProc}, - {N_("Abort F8"),"Abort", AbortProc}, - {N_("Resign F9"), "Resign", ResignProc}, - {"----", NULL, NothingProc}, - {N_("Stop Observing F10"), "Stop Observing", StopObservingProc}, - {N_("Stop Examining F11"), "Stop Examining", StopExaminingProc}, - {N_("Upload to Examine"), "Upload to Examine", UploadProc}, - {"----", NULL, NothingProc}, - {N_("Adjudicate to White"), "Adjudicate to White", AdjuWhiteProc}, - {N_("Adjudicate to Black"), "Adjudicate to Black", AdjuBlackProc}, - {N_("Adjudicate Draw"), "Adjudicate Draw", AdjuDrawProc}, - {NULL, NULL, NULL} -}; - -MenuItem engineMenu[] = { - {N_("Load New Engine ..."), "Load Engine", LoadEngineProc}, - {"----", NULL, NothingProc}, - {N_("Engine #1 Settings ..."), "Engine #1 Settings", FirstSettingsProc}, - {N_("Engine #2 Settings ..."), "Engine #2 Settings", SecondSettingsProc}, - {"----", NULL, NothingProc}, - {N_("Hint"), "Hint", HintProc}, - {N_("Book"), "Book", BookProc}, - {"----", NULL, NothingProc}, - {N_("Move Now Ctrl+M"), "Move Now", MoveNowProc}, - {N_("Retract Move Ctrl+X"), "Retract Move", RetractMoveProc}, - {NULL, NULL, NULL} -}; - -MenuItem optionsMenu[] = { -#define OPTIONSDIALOG -#ifdef OPTIONSDIALOG - {N_("General ..."), "General", OptionsProc}, -#endif - {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_("Match ..."), "Match", MatchOptionsProc}, - {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}, -#ifndef OPTIONSDIALOG - {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 Flag Ctrl+Shift+F"), "Auto Flag", AutoflagProc}, - {N_("Auto Flip View"), "Auto Flip View", AutoflipProc}, - {N_("Blindfold"), "Blindfold", BlindfoldProc}, - {N_("Flash Moves"), "Flash Moves", FlashMovesProc}, -#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_("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_("Show Coords"), "Show Coords", ShowCoordsProc}, - {N_("Hide Thinking Ctrl+Shift+H"), "Hide Thinking", HideThinkingProc}, - {N_("Test Legality Ctrl+Shift+L"), "Test Legality", TestLegalityProc}, - {"----", NULL, NothingProc}, -#endif - {N_("Save Settings Now"), "Save Settings Now", SaveSettingsProc}, - {N_("Save Settings on Exit"), "Save Settings on Exit", SaveOnExitProc}, - {NULL, NULL, NULL} -}; - -MenuItem helpMenu[] = { - {N_("Info XBoard"), "Info XBoard", InfoProc}, - {N_("Man XBoard F1"), "Man XBoard", ManProc}, - {"----", NULL, NothingProc}, - {N_("About XBoard"), "About XBoard", AboutProc}, - {NULL, NULL, NULL} -}; - -Menu menuBar[] = { - {N_("File"), "File", fileMenu}, - {N_("Edit"), "Edit", editMenu}, - {N_("View"), "View", viewMenu}, - {N_("Mode"), "Mode", modeMenu}, - {N_("Action"), "Action", actionMenu}, - {N_("Engine"), "Engine", engineMenu}, - {N_("Options"), "Options", optionsMenu}, - {N_("Help"), "Help", helpMenu}, - {NULL, NULL, NULL} -}; - #define PAUSE_BUTTON "P" MenuItem buttonBar[] = { - {"<<", "<<", ToStartProc}, - {"<", "<", BackwardProc}, - {N_(PAUSE_BUTTON), PAUSE_BUTTON, PauseProc}, - {">", ">", ForwardProc}, - {">>", ">>", ToEndProc}, + {"<<", "<<", ToStartEvent}, + {"<", "<", BackwardEvent}, + {N_(PAUSE_BUTTON), PAUSE_BUTTON, PauseEvent}, + {">", ">", ForwardEvent}, + {">>", ">>", ToEndEvent}, {NULL, NULL, NULL} }; @@ -925,113 +551,11 @@ XtActionsRec boardActions[] = { { "PieceMenuPopup", PieceMenuPopup }, { "WhiteClock", WhiteClock }, { "BlackClock", BlackClock }, - { "ResetProc", ResetProc }, - { "NewVariantProc", NewVariantProc }, - { "LoadGameProc", LoadGameProc }, - { "LoadNextGameProc", LoadNextGameProc }, - { "LoadPrevGameProc", LoadPrevGameProc }, - { "LoadSelectedProc", LoadSelectedProc }, - { "SetFilterProc", SetFilterProc }, - { "ReloadGameProc", ReloadGameProc }, - { "LoadPositionProc", LoadPositionProc }, - { "LoadNextPositionProc", LoadNextPositionProc }, - { "LoadPrevPositionProc", LoadPrevPositionProc }, - { "ReloadPositionProc", ReloadPositionProc }, - { "CopyPositionProc", CopyPositionProc }, - { "PastePositionProc", PastePositionProc }, - { "CopyGameProc", CopyGameProc }, - { "CopyGameListProc", CopyGameListProc }, - { "PasteGameProc", PasteGameProc }, - { "SaveGameProc", SaveGameProc }, - { "SavePositionProc", SavePositionProc }, - { "MailMoveProc", MailMoveProc }, - { "ReloadCmailMsgProc", ReloadCmailMsgProc }, - { "QuitProc", QuitProc }, - { "MachineWhiteProc", MachineWhiteProc }, - { "MachineBlackProc", MachineBlackProc }, - { "AnalysisModeProc", AnalyzeModeProc }, - { "AnalyzeFileProc", AnalyzeFileProc }, - { "TwoMachinesProc", TwoMachinesProc }, - { "IcsClientProc", IcsClientProc }, - { "EditGameProc", EditGameProc }, - { "EditPositionProc", EditPositionProc }, - { "TrainingProc", EditPositionProc }, - { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window - { "EvalGraphProc", EvalGraphProc}, // [HGM] Winboard_x avaluation graph window - { "ShowGameListProc", ShowGameListProc }, - { "ShowMoveListProc", HistoryShowProc}, - { "EditTagsProc", EditCommentProc }, - { "EditBookProc", EditBookProc }, - { "EditCommentProc", EditCommentProc }, - { "IcsInputBoxProc", IcsInputBoxProc }, - { "PauseProc", PauseProc }, - { "AcceptProc", AcceptProc }, - { "DeclineProc", DeclineProc }, - { "RematchProc", RematchProc }, - { "CallFlagProc", CallFlagProc }, - { "DrawProc", DrawProc }, - { "AdjournProc", AdjournProc }, - { "AbortProc", AbortProc }, - { "ResignProc", ResignProc }, - { "AdjuWhiteProc", AdjuWhiteProc }, - { "AdjuBlackProc", AdjuBlackProc }, - { "AdjuDrawProc", AdjuDrawProc }, - { "TypeInProc", TypeInProc }, - { "EnterKeyProc", EnterKeyProc }, - { "UpKeyProc", UpKeyProc }, - { "DownKeyProc", DownKeyProc }, - { "StopObservingProc", StopObservingProc }, - { "StopExaminingProc", StopExaminingProc }, - { "UploadProc", UploadProc }, - { "BackwardProc", BackwardProc }, - { "ForwardProc", ForwardProc }, + { "MenuItem", KeyBindingProc }, // [HGM] generic handler for key bindings + { "QuitProc", QuitWrapper }, + { "ManProc", ManInner }, { "TempBackwardProc", TempBackwardProc }, { "TempForwardProc", TempForwardProc }, - { "ToStartProc", ToStartProc }, - { "ToEndProc", ToEndProc }, - { "RevertProc", RevertProc }, - { "AnnotateProc", AnnotateProc }, - { "TruncateGameProc", TruncateGameProc }, - { "MoveNowProc", MoveNowProc }, - { "RetractMoveProc", RetractMoveProc }, - { "EngineMenuProc", (XtActionProc) EngineMenuProc }, - { "UciMenuProc", (XtActionProc) UciMenuProc }, - { "TimeControlProc", (XtActionProc) TimeControlProc }, - { "FlipViewProc", FlipViewProc }, - { "PonderNextMoveProc", PonderNextMoveProc }, -#ifndef OPTIONSDIALOG - { "AlwaysQueenProc", AlwaysQueenProc }, - { "AnimateDraggingProc", AnimateDraggingProc }, - { "AnimateMovingProc", AnimateMovingProc }, - { "AutoflagProc", AutoflagProc }, - { "AutoflipProc", AutoflipProc }, - { "BlindfoldProc", BlindfoldProc }, - { "FlashMovesProc", FlashMovesProc }, -#if HIGHDRAG - { "HighlightDraggingProc", HighlightDraggingProc }, -#endif - { "HighlightLastMoveProc", HighlightLastMoveProc }, -// { "IcsAlarmProc", IcsAlarmProc }, - { "MoveSoundProc", MoveSoundProc }, - { "PeriodicUpdatesProc", PeriodicUpdatesProc }, - { "PopupExitMessageProc", PopupExitMessageProc }, - { "PopupMoveErrorsProc", PopupMoveErrorsProc }, -// { "PremoveProc", PremoveProc }, - { "ShowCoordsProc", ShowCoordsProc }, - { "ShowThinkingProc", ShowThinkingProc }, - { "HideThinkingProc", HideThinkingProc }, - { "TestLegalityProc", TestLegalityProc }, -#endif - { "SaveSettingsProc", SaveSettingsProc }, - { "SaveOnExitProc", SaveOnExitProc }, - { "InfoProc", InfoProc }, - { "ManProc", ManProc }, - { "HintProc", HintProc }, - { "BookProc", BookProc }, - { "AboutGameProc", AboutGameProc }, - { "AboutProc", AboutProc }, - { "DebugProc", DebugProc }, - { "NothingProc", NothingProc }, { "CommentClick", (XtActionProc) CommentClick }, { "CommentPopDown", (XtActionProc) CommentPopDown }, { "TagsPopDown", (XtActionProc) TagsPopDown }, @@ -1047,74 +571,81 @@ XtActionsRec boardActions[] = { { "GenericPopDown", (XtActionProc) GenericPopDown }, { "CopyMemoProc", (XtActionProc) CopyMemoProc }, { "SelectMove", (XtActionProc) SelectMove }, + { "LoadSelectedProc", LoadSelectedProc }, + { "SetFilterProc", SetFilterProc }, + { "TypeInProc", TypeInProc }, + { "EnterKeyProc", EnterKeyProc }, + { "UpKeyProc", UpKeyProc }, + { "DownKeyProc", DownKeyProc }, }; char globalTranslations[] = - ":F9: ResignProc() \n \ - :Ctrln: ResetProc() \n \ - :MetaV: NewVariantProc() \n \ - :Ctrlo: LoadGameProc() \n \ - :MetaNext: LoadNextGameProc() \n \ - :MetaPrior: LoadPrevGameProc() \n \ + ":F9: MenuItem(ResignProc) \n \ + :Ctrln: MenuItem(NewGame) \n \ + :MetaV: MenuItem(NewVariant) \n \ + :Ctrlo: MenuItem(LoadGame) \n \ + :MetaNext: MenuItem(LoadNextGameProc) \n \ + :MetaPrior: MenuItem(LoadPrevGameProc) \n \ :CtrlDown: LoadSelectedProc(3) \n \ :CtrlUp: LoadSelectedProc(-3) \n \ - :Ctrls: SaveGameProc() \n \ - :Ctrlc: CopyGameProc() \n \ - :Ctrlv: PasteGameProc() \n \ - :CtrlO: LoadPositionProc() \n \ - :ShiftNext: LoadNextPositionProc() \n \ - :ShiftPrior: LoadPrevPositionProc() \n \ - :CtrlS: SavePositionProc() \n \ - :CtrlC: CopyPositionProc() \n \ - :CtrlV: PastePositionProc() \n \ - :Ctrlq: QuitProc() \n \ - :Ctrlw: MachineWhiteProc() \n \ - :Ctrlb: MachineBlackProc() \n \ - :Ctrlt: TwoMachinesProc() \n \ - :Ctrla: AnalysisModeProc() \n \ - :Ctrlg: AnalyzeFileProc() \n \ - :Ctrle: EditGameProc() \n \ - :CtrlE: EditPositionProc() \n \ - :MetaO: EngineOutputProc() \n \ - :MetaE: EvalGraphProc() \n \ - :MetaG: ShowGameListProc() \n \ - :MetaH: ShowMoveListProc() \n \ - :Pause: PauseProc() \n \ - :F3: AcceptProc() \n \ - :F4: DeclineProc() \n \ - :F12: RematchProc() \n \ - :F5: CallFlagProc() \n \ - :F6: DrawProc() \n \ - :F7: AdjournProc() \n \ - :F8: AbortProc() \n \ - :F10: StopObservingProc() \n \ - :F11: StopExaminingProc() \n \ - :Meta CtrlF12: DebugProc() \n \ - :MetaEnd: ToEndProc() \n \ - :MetaRight: ForwardProc() \n \ - :MetaHome: ToStartProc() \n \ - :MetaLeft: BackwardProc() \n \ - :Left: BackwardProc() \n \ - :Right: ForwardProc() \n \ - :Home: RevertProc() \n \ - :End: TruncateGameProc() \n \ - :Ctrlm: MoveNowProc() \n \ - :Ctrlx: RetractMoveProc() \n \ - :MetaJ: EngineMenuProc() \n \ - :MetaU: UciMenuProc() \n \ - :MetaT: TimeControlProc() \n \ - :CtrlP: PonderNextMoveProc() \n " + :Ctrls: MenuItem(SaveGame) \n \ + :Ctrlc: MenuItem(CopyGame) \n \ + :Ctrlv: MenuItem(PasteGame) \n \ + :CtrlO: MenuItem(LoadPosition) \n \ + :ShiftNext: MenuItem(LoadNextPositionProc) \n \ + :ShiftPrior: MenuItem(LoadPrevPositionProc) \n \ + :CtrlS: MenuItem(SavePosition) \n \ + :CtrlC: MenuItem(CopyPosition) \n \ + :CtrlV: MenuItem(PastePosition) \n \ + :Ctrlq: MenuItem(Exit) \n \ + :Ctrlw: MenuItem(MachineWhite) \n \ + :Ctrlb: MenuItem(MachineBlack) \n \ + :Ctrlt: MenuItem(TwoMachines) \n \ + :Ctrla: MenuItem(AnalysisMode) \n \ + :Ctrlg: MenuItem(AnalyzeFile) \n \ + :Ctrle: MenuItem(EditGame) \n \ + :CtrlE: MenuItem(EditPosition) \n \ + :MetaO: MenuItem(ShowEngineOutput) \n \ + :MetaE: MenuItem(ShowEvaluationGraph) \n \ + :MetaG: MenuItem(ShowGameList) \n \ + :MetaH: MenuItem(ShowMoveHistory) \n \ + :Pause: MenuItem(Pause) \n \ + :F3: MenuItem(Accept) \n \ + :F4: MenuItem(Decline) \n \ + :F12: MenuItem(Rematch) \n \ + :F5: MenuItem(CallFlag) \n \ + :F6: MenuItem(Draw) \n \ + :F7: MenuItem(Adjourn) \n \ + :F8: MenuItem(Abort) \n \ + :F10: MenuItem(StopObserving) \n \ + :F11: MenuItem(StopExamining) \n \ + :Ctrld: MenuItem(DebugProc) \n \ + :Meta CtrlF12: MenuItem(DebugProc) \n \ + :MetaEnd: MenuItem(ToEnd) \n \ + :MetaRight: MenuItem(Forward) \n \ + :MetaHome: MenuItem(ToStart) \n \ + :MetaLeft: MenuItem(Backward) \n \ + :Left: MenuItem(Backward) \n \ + :Right: MenuItem(Forward) \n \ + :Home: MenuItem(Revert) \n \ + :End: MenuItem(TruncateGame) \n \ + :Ctrlm: MenuItem(MoveNow) \n \ + :Ctrlx: MenuItem(RetractMove) \n \ + :MetaJ: MenuItem(Adjudications) \n \ + :MetaU: MenuItem(CommonEngine) \n \ + :MetaT: MenuItem(TimeControl) \n \ + :CtrlP: MenuItem(PonderNextMove) \n " #ifndef OPTIONSDIALOG "\ - :CtrlQ: AlwaysQueenProc() \n \ - :CtrlF: AutoflagProc() \n \ - :CtrlA: AnimateMovingProc() \n \ - :CtrlL: TestLegalityProc() \n \ - :CtrlH: HideThinkingProc() \n " + :CtrlQ: MenuItem(AlwaysQueenProc) \n \ + :CtrlF: MenuItem(AutoflagProc) \n \ + :CtrlA: MenuItem(AnimateMovingProc) \n \ + :CtrlL: MenuItem(TestLegalityProc) \n \ + :CtrlH: MenuItem(HideThinkingProc) \n " #endif "\ - :F1: ManProc() \n \ - :F2: FlipViewProc() \n \ + :F1: MenuItem(Manual) \n \ + :F2: MenuItem(FlipView) \n \ :Return: TempBackwardProc() \n \ :Return: TempForwardProc() \n"; @@ -1124,7 +655,9 @@ char boardTranslations[] = : HandleUserMove(0) \n \ : AnimateUserMove() \n \ : HandlePV() \n \ + : HandlePV() \n \ : PieceMenuPopup(menuB) \n \ + : PieceMenuPopup(menuB) \n \ Shift: XawPositionSimpleMenu(menuB) XawPositionSimpleMenu(menuD)\ PieceMenuPopup(menuB) \n \ Any: XawPositionSimpleMenu(menuW) XawPositionSimpleMenu(menuD) \ @@ -1552,6 +1085,7 @@ ParseCommPortSettings (char *s) } extern Widget engineOutputShell; +int frameX, frameY; void GetActualPlacement (Widget wg, WindowPlacement *wp) @@ -1559,20 +1093,20 @@ GetActualPlacement (Widget wg, WindowPlacement *wp) Arg args[16]; Dimension w, h; Position x, y; - int i; + XWindowAttributes winAt; + Window win, dummy; + int i, rx, ry; if(!wg) return; - i = 0; - XtSetArg(args[i], XtNx, &x); i++; - XtSetArg(args[i], XtNy, &y); i++; - XtSetArg(args[i], XtNwidth, &w); i++; - XtSetArg(args[i], XtNheight, &h); i++; - XtGetValues(wg, args, i); - wp->x = x - 4; - wp->y = y - 23; - wp->height = h; - wp->width = w; + win = XtWindow(wg); + XGetWindowAttributes(xDisplay, win, &winAt); // this works, where XtGetValues on XtNx, XtNy does not! + XTranslateCoordinates (xDisplay, win, winAt.root, -winAt.border_width, -winAt.border_width, &rx, &ry, &dummy); + wp->x = rx - winAt.x; + wp->y = ry - winAt.y; + wp->height = winAt.height; + wp->width = winAt.width; + frameX = winAt.x; frameY = winAt.y; // remember to decide if windows touch } void @@ -1742,6 +1276,9 @@ InitDrawingSizes (BoardSize boardSize, int flags) shellArgs[4].value = shellArgs[2].value = w; shellArgs[5].value = shellArgs[3].value = h; XtSetValues(shellWidget, &shellArgs[0], 6); + + XSync(xDisplay, False); + DelayedDrag(); } // [HGM] pieces: tailor piece bitmaps to needs of specific variant @@ -1815,9 +1352,11 @@ InitDrawingSizes (BoardSize boardSize, int flags) } } } + oldMono = -10; // kludge to force recreation of animation masks + oldVariant = gameInfo.variant; } #if HAVE_LIBXPM - if(appData.monoMode == oldMono) + if(appData.monoMode != oldMono) CreateAnimVars(); #endif oldMono = appData.monoMode; @@ -1848,79 +1387,35 @@ ParseIcsTextColors () } int -MakeColors () -{ // [HGM] taken out of main(), so it can be called from BoardOptions dialog +MakeOneColor (char *name, Pixel *color) +{ XrmValue vFrom, vTo; - int forceMono = False; - if (!appData.monoMode) { - vFrom.addr = (caddr_t) appData.lightSquareColor; - vFrom.size = strlen(appData.lightSquareColor); + vFrom.addr = (caddr_t) name; + vFrom.size = strlen(name); XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo); if (vTo.addr == NULL) { appData.monoMode = True; - forceMono = True; + return 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; + *color = *(Pixel *) vTo.addr; } } + return False; +} - 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; - } - } +int +MakeColors () +{ // [HGM] taken out of main(), so it can be called from BoardOptions dialog + int forceMono = False; + + forceMono |= MakeOneColor(appData.lightSquareColor, &lightSquareColor); + forceMono |= MakeOneColor(appData.darkSquareColor, &darkSquareColor); + forceMono |= MakeOneColor(appData.whitePieceColor, &whitePieceColor); + forceMono |= MakeOneColor(appData.blackPieceColor, &blackPieceColor); + forceMono |= MakeOneColor(appData.highlightSquareColor, &highlightSquareColor); + forceMono |= MakeOneColor(appData.premoveHighlightColor, &premoveHighlightColor); - 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; } @@ -2174,10 +1669,13 @@ XBoard square size (hint): %d\n\ /* For the coordFont, use the 0th font of the fontset. */ XFontSet coordFontSet = CreateFontSet(appData.coordFont); XFontStruct **font_struct_list; + XFontSetExtents *fontSize; char **font_name_list; XFontsOfFontSet(coordFontSet, &font_struct_list, &font_name_list); coordFontID = XLoadFont(xDisplay, font_name_list[0]); coordFontStruct = XQueryFont(xDisplay, coordFontID); + fontSize = XExtentsOfFontSet(fontSet); // [HGM] figure out how much vertical space font takes + textHeight = fontSize->max_logical_extent.height + 5; // add borderWidth } #else appData.font = FindFont(appData.font, fontPxlSize); @@ -2460,6 +1958,7 @@ XBoard square size (hint): %d\n\ programName, gres, w, h, wr, hr); } /* !! end hack */ + if(!textHeight) textHeight = hr; // [HGM] if !NLS textHeight is still undefined, and we grab it from here XtSetArg(args[0], XtNleft, XtChainLeft); // [HGM] glue ends for good run-time sizing XtSetArg(args[1], XtNright, XtChainRight); XtSetValues(messageWidget, args, 2); @@ -2497,104 +1996,7 @@ XBoard square size (hint): %d\n\ */ ReadBitmap(&xMarkPixmap, "checkmark.bm", checkmark_bits, checkmark_width, checkmark_height); - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); -#ifndef OPTIONSDIALOG - if (appData.alwaysPromoteToQueen) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"), - args, 1); - } - if (appData.animateDragging) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Animate Dragging"), - args, 1); - } - if (appData.animate) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), - args, 1); - } - if (appData.autoCallFlag) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"), - args, 1); - } - if (appData.autoFlipView) { - XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Auto Flip View"), - args, 1); - } - if (appData.blindfold) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Blindfold"), args, 1); - } - if (appData.flashCount > 0) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Flash Moves"), - args, 1); - } -#if HIGHDRAG - if (appData.highlightDragging) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Dragging"), - args, 1); - } -#endif - if (appData.highlightLastMove) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Last Move"), - args, 1); - } - 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.oneClick) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.OneClick"), args, 1); - } - if (appData.periodicUpdates) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Periodic Updates"), args, 1); - } - if (appData.ponderNextMove) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Ponder Next Move"), args, 1); - } - if (appData.popupExitMessage) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Popup Exit Message"), args, 1); - } - if (appData.popupMoveErrors) { - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Popup Move Errors"), args, 1); - } -// if (appData.premove) { -// XtSetValues(XtNameToWidget(menuBarWidget, -// "menuOptions.Premove"), args, 1); -// } - if (appData.showCoords) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"), - args, 1); - } - if (appData.hideThinkingFromHuman) { - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"), - args, 1); - } - if (appData.testLegality) { - XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Test Legality"), - args, 1); - } -#endif - if (saveSettingsOnExit) { - XtSetValues(XtNameToWidget(menuBarWidget,"menuOptions.Save Settings on Exit"), - args, 1); - } + InitMenuMarkers(); /* * Create an icon. @@ -2654,6 +2056,8 @@ XBoard square size (hint): %d\n\ /* end why */ XtAddEventHandler(formWidget, KeyPressMask, False, (XtEventHandler) MoveTypeInProc, NULL); + XtAddEventHandler(shellWidget, StructureNotifyMask, False, + (XtEventHandler) EventProc, NULL); /* [AS] Restore layout */ if( wpMoveHistory.visible ) { @@ -2688,6 +2092,7 @@ XBoard square size (hint): %d\n\ signal(SIGUSR1, CmailSigHandler); } } + gameInfo.boardWidth = 0; // [HGM] pieces: kludge to ensure InitPosition() calls InitDrawingSizes() InitPosition(TRUE); // XtSetKeyboardFocus(shellWidget, formWidget); @@ -2787,294 +2192,6 @@ ResetFrontEnd () return; } -typedef struct { - char *name; - Boolean value; -} Enables; - -void -GreyRevert (Boolean grey) -{ - Widget w; - if (!menuBarWidget) return; - w = XtNameToWidget(menuBarWidget, "menuEdit.Revert"); - if (w == NULL) { - DisplayError("menuEdit.Revert", 0); - } else { - XtSetSensitive(w, !grey); - } - w = XtNameToWidget(menuBarWidget, "menuEdit.Annotate"); - if (w == NULL) { - DisplayError("menuEdit.Annotate", 0); - } else { - XtSetSensitive(w, !grey); - } -} - -void -SetMenuEnables (Enables *enab) -{ - Widget w; - if (!menuBarWidget) return; - while (enab->name != NULL) { - w = XtNameToWidget(menuBarWidget, enab->name); - if (w == NULL) { - DisplayError(enab->name, 0); - } else { - XtSetSensitive(w, enab->value); - } - enab++; - } -} - -Enables icsEnables[] = { - { "menuFile.Mail Move", False }, - { "menuFile.Reload CMail Message", False }, - { "menuMode.Machine Black", False }, - { "menuMode.Machine White", False }, - { "menuMode.Analysis Mode", False }, - { "menuMode.Analyze File", False }, - { "menuMode.Two Machines", False }, - { "menuMode.Machine Match", False }, -#ifndef ZIPPY - { "menuEngine.Hint", False }, - { "menuEngine.Book", False }, - { "menuEngine.Move Now", False }, -#ifndef OPTIONSDIALOG - { "menuOptions.Periodic Updates", False }, - { "menuOptions.Hide Thinking", False }, - { "menuOptions.Ponder Next Move", False }, -#endif -#endif - { "menuEngine.Engine #1 Settings", False }, - { "menuEngine.Engine #2 Settings", False }, - { "menuEngine.Load Engine", False }, - { "menuEdit.Annotate", False }, - { "menuOptions.Match", False }, - { NULL, False } -}; - -Enables ncpEnables[] = { - { "menuFile.Mail Move", False }, - { "menuFile.Reload CMail Message", False }, - { "menuMode.Machine White", False }, - { "menuMode.Machine Black", False }, - { "menuMode.Analysis Mode", False }, - { "menuMode.Analyze File", False }, - { "menuMode.Two Machines", False }, - { "menuMode.Machine Match", False }, - { "menuMode.ICS Client", False }, - { "menuView.ICStex", False }, - { "menuView.ICS Input Box", False }, - { "Action", False }, - { "menuEdit.Revert", False }, - { "menuEdit.Annotate", False }, - { "menuEngine.Engine #1 Settings", False }, - { "menuEngine.Engine #2 Settings", False }, - { "menuEngine.Move Now", False }, - { "menuEngine.Retract Move", False }, - { "menuOptions.ICS", False }, -#ifndef OPTIONSDIALOG - { "menuOptions.Auto Flag", False }, - { "menuOptions.Auto Flip View", False }, -// { "menuOptions.ICS Alarm", False }, - { "menuOptions.Move Sound", False }, - { "menuOptions.Hide Thinking", False }, - { "menuOptions.Periodic Updates", False }, - { "menuOptions.Ponder Next Move", False }, -#endif - { "menuEngine.Hint", False }, - { "menuEngine.Book", False }, - { NULL, False } -}; - -Enables gnuEnables[] = { - { "menuMode.ICS Client", False }, - { "menuView.ICStex", False }, - { "menuView.ICS Input Box", False }, - { "menuAction.Accept", False }, - { "menuAction.Decline", False }, - { "menuAction.Rematch", False }, - { "menuAction.Adjourn", False }, - { "menuAction.Stop Examining", False }, - { "menuAction.Stop Observing", False }, - { "menuAction.Upload to Examine", False }, - { "menuEdit.Revert", False }, - { "menuEdit.Annotate", 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 */ - /* menu options are still available */ - - { "menuFile.Mail Move", False }, - { "menuFile.Reload CMail Message", False }, - // [HGM] The following have been added to make a switch from ncp to GNU mode possible - { "menuMode.Machine White", True }, - { "menuMode.Machine Black", True }, - { "menuMode.Analysis Mode", True }, - { "menuMode.Analyze File", True }, - { "menuMode.Two Machines", True }, - { "menuMode.Machine Match", True }, - { "menuEngine.Engine #1 Settings", True }, - { "menuEngine.Engine #2 Settings", True }, - { "menuEngine.Hint", True }, - { "menuEngine.Book", True }, - { "menuEngine.Move Now", True }, - { "menuEngine.Retract Move", True }, - { "Action", True }, - { NULL, False } -}; - -Enables cmailEnables[] = { - { "Action", True }, - { "menuAction.Call Flag", False }, - { "menuAction.Draw", True }, - { "menuAction.Adjourn", False }, - { "menuAction.Abort", False }, - { "menuAction.Stop Observing", False }, - { "menuAction.Stop Examining", False }, - { "menuFile.Mail Move", True }, - { "menuFile.Reload CMail Message", True }, - { NULL, False } -}; - -Enables trainingOnEnables[] = { - { "menuMode.Edit Comment", False }, - { "menuMode.Pause", False }, - { "menuEdit.Forward", False }, - { "menuEdit.Backward", False }, - { "menuEdit.Forward to End", False }, - { "menuEdit.Back to Start", False }, - { "menuEngine.Move Now", False }, - { "menuEdit.Truncate Game", False }, - { NULL, False } -}; - -Enables trainingOffEnables[] = { - { "menuMode.Edit Comment", True }, - { "menuMode.Pause", True }, - { "menuEdit.Forward", True }, - { "menuEdit.Backward", True }, - { "menuEdit.Forward to End", True }, - { "menuEdit.Back to Start", True }, - { "menuEngine.Move Now", True }, - { "menuEdit.Truncate Game", True }, - { NULL, False } -}; - -Enables machineThinkingEnables[] = { - { "menuFile.Load Game", False }, -// { "menuFile.Load Next Game", False }, -// { "menuFile.Load Previous Game", False }, -// { "menuFile.Reload Same Game", False }, - { "menuEdit.Paste Game", False }, - { "menuFile.Load Position", False }, -// { "menuFile.Load Next Position", False }, -// { "menuFile.Load Previous Position", False }, -// { "menuFile.Reload Same Position", False }, - { "menuEdit.Paste Position", False }, - { "menuMode.Machine White", False }, - { "menuMode.Machine Black", False }, - { "menuMode.Two Machines", False }, -// { "menuMode.Machine Match", False }, - { "menuEngine.Retract Move", False }, - { NULL, False } -}; - -Enables userThinkingEnables[] = { - { "menuFile.Load Game", True }, -// { "menuFile.Load Next Game", True }, -// { "menuFile.Load Previous Game", True }, -// { "menuFile.Reload Same Game", True }, - { "menuEdit.Paste Game", True }, - { "menuFile.Load Position", True }, -// { "menuFile.Load Next Position", True }, -// { "menuFile.Load Previous Position", True }, -// { "menuFile.Reload Same Position", True }, - { "menuEdit.Paste Position", True }, - { "menuMode.Machine White", True }, - { "menuMode.Machine Black", True }, - { "menuMode.Two Machines", True }, -// { "menuMode.Machine Match", True }, - { "menuEngine.Retract Move", True }, - { NULL, False } -}; - -void -SetICSMode () -{ - SetMenuEnables(icsEnables); - -#if ZIPPY - if (appData.zippyPlay && !appData.noChessProgram) { /* [DM] icsEngineAnalyze */ - XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True); - XtSetSensitive(XtNameToWidget(menuBarWidget, "menuEngine.Engine #1 Settings"), True); - } -#endif -} - -void -SetNCPMode () -{ - SetMenuEnables(ncpEnables); -} - -void -SetGNUMode () -{ - SetMenuEnables(gnuEnables); -} - -void -SetCmailMode () -{ - SetMenuEnables(cmailEnables); -} - -void -SetTrainingModeOn () -{ - SetMenuEnables(trainingOnEnables); - if (appData.showButtonBar) { - XtSetSensitive(buttonBarWidget, False); - } - CommentPopDown(); -} - -void -SetTrainingModeOff () -{ - SetMenuEnables(trainingOffEnables); - if (appData.showButtonBar) { - XtSetSensitive(buttonBarWidget, True); - } -} - -void -SetUserThinkingEnables () -{ - if (appData.noChessProgram) return; - SetMenuEnables(userThinkingEnables); -} - -void -SetMachineThinkingEnables () -{ - if (appData.noChessProgram) return; - SetMenuEnables(machineThinkingEnables); - switch (gameMode) { - case MachinePlaysBlack: - case MachinePlaysWhite: - case TwoMachinesPlay: - XtSetSensitive(XtNameToWidget(menuBarWidget, - ModeToWidgetName(gameMode)), True); - break; - default: - break; - } -} - // [HGM] code borrowed from winboard.c (which should thus go to backend.c!) #define HISTORY_SIZE 64 static char *history[HISTORY_SIZE]; @@ -3302,6 +2419,16 @@ DeleteGCs () } } +static GC +CreateOneGC (XGCValues *gc_values, Pixel foreground, Pixel background) +{ + XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground + | GCBackground | GCFunction | GCPlaneMask; + gc_values->foreground = foreground; + gc_values->background = background; + return XtGetGC(shellWidget, value_mask, gc_values); +} + void CreateGCs (int redo) { @@ -3309,6 +2436,8 @@ CreateGCs (int redo) | GCBackground | GCFunction | GCPlaneMask; XGCValues gc_values; GC copyInvertedGC; + Pixel white = XWhitePixel(xDisplay, xScreen); + Pixel black = XBlackPixel(xDisplay, xScreen); gc_values.plane_mask = AllPlanes; gc_values.line_width = lineGap; @@ -3318,40 +2447,25 @@ CreateGCs (int redo) 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 = XWhitePixel(xDisplay, xScreen); - coordGC = XtGetGC(shellWidget, value_mask, &gc_values); + coordGC = CreateOneGC(&gc_values, black, white); XSetFont(xDisplay, coordGC, coordFontID); // [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); + countGC = CreateOneGC(&gc_values, white, black); XSetFont(xDisplay, countGC, countFontID); } - gc_values.foreground = XBlackPixel(xDisplay, xScreen); - gc_values.background = XBlackPixel(xDisplay, xScreen); - lineGC = XtGetGC(shellWidget, value_mask, &gc_values); + lineGC = CreateOneGC(&gc_values, black, black); if (appData.monoMode) { - gc_values.foreground = XWhitePixel(xDisplay, xScreen); - gc_values.background = XWhitePixel(xDisplay, xScreen); - highlineGC = XtGetGC(shellWidget, value_mask, &gc_values); - gc_values.foreground = XWhitePixel(xDisplay, xScreen); - gc_values.background = XBlackPixel(xDisplay, xScreen); - lightSquareGC = wbPieceGC - = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = XBlackPixel(xDisplay, xScreen); - gc_values.background = XWhitePixel(xDisplay, xScreen); - darkSquareGC = bwPieceGC - = XtGetGC(shellWidget, value_mask, &gc_values); + highlineGC = CreateOneGC(&gc_values, white, white); + lightSquareGC = wbPieceGC = CreateOneGC(&gc_values, white, black); + darkSquareGC = bwPieceGC = CreateOneGC(&gc_values, black, white); if (DefaultDepth(xDisplay, xScreen) == 1) { /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */ gc_values.function = GXcopyInverted; - copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values); + copyInvertedGC = CreateOneGC(&gc_values, black, white); gc_values.function = GXcopy; if (XBlackPixel(xDisplay, xScreen) == 1) { bwPieceGC = darkSquareGC; @@ -3362,49 +2476,18 @@ CreateGCs (int redo) } } } else { - gc_values.foreground = highlightSquareColor; - gc_values.background = highlightSquareColor; - highlineGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = premoveHighlightColor; - gc_values.background = premoveHighlightColor; - prelineGC = XtGetGC(shellWidget, value_mask, &gc_values); - gc_values.foreground = lightSquareColor; - gc_values.background = darkSquareColor; - lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = darkSquareColor; - gc_values.background = lightSquareColor; - darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = jailSquareColor; - gc_values.background = jailSquareColor; - jailSquareGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = whitePieceColor; - gc_values.background = darkSquareColor; - wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = whitePieceColor; - gc_values.background = lightSquareColor; - wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = whitePieceColor; - gc_values.background = jailSquareColor; - wjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = blackPieceColor; - gc_values.background = darkSquareColor; - bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = blackPieceColor; - gc_values.background = lightSquareColor; - blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); - - gc_values.foreground = blackPieceColor; - gc_values.background = jailSquareColor; - bjPieceGC = XtGetGC(shellWidget, value_mask, &gc_values); + highlineGC = CreateOneGC(&gc_values, highlightSquareColor, highlightSquareColor); + prelineGC = CreateOneGC(&gc_values, premoveHighlightColor, premoveHighlightColor); + lightSquareGC = CreateOneGC(&gc_values, lightSquareColor, darkSquareColor); + darkSquareGC = CreateOneGC(&gc_values, darkSquareColor, lightSquareColor); + jailSquareGC = CreateOneGC(&gc_values, jailSquareColor, jailSquareColor); + wdPieceGC = CreateOneGC(&gc_values, whitePieceColor, darkSquareColor); + wlPieceGC = CreateOneGC(&gc_values, whitePieceColor, lightSquareColor); + wjPieceGC = CreateOneGC(&gc_values, whitePieceColor, jailSquareColor); + bdPieceGC = CreateOneGC(&gc_values, blackPieceColor, darkSquareColor); + blPieceGC = CreateOneGC(&gc_values, blackPieceColor, lightSquareColor); + bjPieceGC = CreateOneGC(&gc_values, blackPieceColor, jailSquareColor); } } @@ -3878,77 +2961,183 @@ CreateGrid () } } +int nrOfMenuItems = 7; +Widget menuWidget[150]; +MenuListItem menuItemList[150] = { + { "LoadNextGameProc", LoadNextGameProc }, + { "LoadPrevGameProc", LoadPrevGameProc }, + { "ReloadGameProc", ReloadGameProc }, + { "ReloadPositionProc", ReloadPositionProc }, +#ifndef OPTIONSDIALOG + { "AlwaysQueenProc", AlwaysQueenProc }, + { "AnimateDraggingProc", AnimateDraggingProc }, + { "AnimateMovingProc", AnimateMovingProc }, + { "AutoflagProc", AutoflagProc }, + { "AutoflipProc", AutoflipProc }, + { "BlindfoldProc", BlindfoldProc }, + { "FlashMovesProc", FlashMovesProc }, +#if HIGHDRAG + { "HighlightDraggingProc", HighlightDraggingProc }, +#endif + { "HighlightLastMoveProc", HighlightLastMoveProc }, +// { "IcsAlarmProc", IcsAlarmProc }, + { "MoveSoundProc", MoveSoundProc }, + { "PeriodicUpdatesProc", PeriodicUpdatesProc }, + { "PopupExitMessageProc", PopupExitMessageProc }, + { "PopupMoveErrorsProc", PopupMoveErrorsProc }, +// { "PremoveProc", PremoveProc }, + { "ShowCoordsProc", ShowCoordsProc }, + { "ShowThinkingProc", ShowThinkingProc }, + { "HideThinkingProc", HideThinkingProc }, + { "TestLegalityProc", TestLegalityProc }, +#endif + { "AboutGameProc", AboutGameEvent }, + { "DebugProc", DebugProc }, + { "NothingProc", NothingProc }, + {NULL, NothingProc} +}; + +void +MarkMenuItem (char *menuRef, int state) +{ + int nr = MenuToNumber(menuRef); + if(nr >= 0) { + Arg args[2]; + XtSetArg(args[0], XtNleftBitmap, state ? xMarkPixmap : None); + XtSetValues(menuWidget[nr], args, 1); + } +} + +void +EnableMenuItem (char *menuRef, int state) +{ + int nr = MenuToNumber(menuRef); + if(nr >= 0) XtSetSensitive(menuWidget[nr], state); +} + +void +EnableButtonBar (int state) +{ + XtSetSensitive(buttonBarWidget, state); +} + + +void +SetMenuEnables (Enables *enab) +{ + while (enab->name != NULL) { + EnableMenuItem(enab->name, enab->value); + enab++; + } +} + +int +Equal(char *p, char *s) +{ // compare strings skipping spaces in second + while(*s) { + if(*s == ' ') { s++; continue; } + if(*s++ != *p++) return 0; + } + return !*p; +} + +void +KeyBindingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ // [HGM] new method of key binding: specify MenuItem(FlipView) in stead of FlipViewProc in translation string + int i; + if(*nprms == 0) return; + for(i=0; menuItemList[i].name; i++) { + if(Equal(prms[0], menuItemList[i].name)) { + (menuItemList[i].proc) (); + return; + } + } +} + static void MenuBarSelect (Widget w, caddr_t addr, caddr_t index) { - XtActionProc proc = (XtActionProc) addr; + MenuProc *proc = (MenuProc *) addr; - (proc)(NULL, NULL, NULL, NULL); + (proc)(); } +static void +MenuEngineSelect (Widget w, caddr_t addr, caddr_t index) +{ + RecentEngineEvent((int) (intptr_t) addr); +} + +// some stuff that must remain in front-end +static Widget mainBar, currentMenu; +static int wtot, nr = 0, widths[10]; + void -CreateMenuBarPopup (Widget parent, String name, Menu *mb) +AppendMenuItem (char *text, char *name, MenuProc *action) { int j; - Widget menu, entry; - MenuItem *mi; + Widget entry; Arg args[16]; - menu = XtCreatePopupShell(name, simpleMenuWidgetClass, - parent, NULL, 0); j = 0; XtSetArg(args[j], XtNleftMargin, 20); j++; XtSetArg(args[j], XtNrightMargin, 20); j++; - mi = mb->mi; - while (mi->string != NULL) { - if (strcmp(mi->string, "----") == 0) { - entry = XtCreateManagedWidget(_(mi->string), smeLineObjectClass, - menu, args, j); + + if (strcmp(text, "----") == 0) { + entry = XtCreateManagedWidget(text, smeLineObjectClass, + currentMenu, args, j); } else { - XtSetArg(args[j], XtNlabel, XtNewString(_(mi->string))); - entry = XtCreateManagedWidget(mi->ref, smeBSBObjectClass, - menu, args, j+1); + XtSetArg(args[j], XtNlabel, XtNewString(_(text))); + entry = XtCreateManagedWidget(name, smeBSBObjectClass, + currentMenu, args, j+1); XtAddCallback(entry, XtNcallback, - (XtCallbackProc) MenuBarSelect, - (caddr_t) mi->proc); + (XtCallbackProc) (strcmp(name, "recent") ? MenuBarSelect : MenuEngineSelect), + (caddr_t) action); + menuWidget[nrOfMenuItems] = entry; } - mi++; - } +} + +void +CreateMenuButton (char *name, Menu *mb) +{ // create menu button on main bar, and shell for pull-down list + int i, j; + Arg args[16]; + Dimension w; + + j = 0; + XtSetArg(args[j], XtNmenuName, XtNewString(name)); j++; + XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++; + XtSetArg(args[j], XtNborderWidth, 0); j++; + mb->subMenu = XtCreateManagedWidget(mb->name, menuButtonWidgetClass, + mainBar, args, j); + currentMenu = XtCreatePopupShell(name, simpleMenuWidgetClass, + mainBar, NULL, 0); + j = 0; + XtSetArg(args[j], XtNwidth, &w); j++; + XtGetValues(mb->subMenu, args, j); + wtot += mb->textWidth = widths[nr++] = w; } Widget CreateMenuBar (Menu *mb, int boardWidth) { - int i, j, nr = 0, wtot = 0, widths[10]; - Widget menuBar; + int i, j; Arg args[16]; char menuName[MSG_SIZ]; Dimension w; Menu *ma = mb; + // create bar itself j = 0; XtSetArg(args[j], XtNorientation, XtorientHorizontal); j++; XtSetArg(args[j], XtNvSpace, 0); j++; XtSetArg(args[j], XtNborderWidth, 0); j++; - menuBar = XtCreateWidget("menuBar", boxWidgetClass, + mainBar = XtCreateWidget("menuBar", boxWidgetClass, formWidget, args, j); - while (mb->name != NULL) { - safeStrCpy(menuName, "menu", sizeof(menuName)/sizeof(menuName[0]) ); - strncat(menuName, mb->ref, MSG_SIZ - strlen(menuName) - 1); - j = 0; - XtSetArg(args[j], XtNmenuName, XtNewString(menuName)); j++; - XtSetArg(args[j], XtNlabel, XtNewString(_(mb->name))); j++; - XtSetArg(args[j], XtNborderWidth, 0); j++; - mb->subMenu = XtCreateManagedWidget(mb->name, menuButtonWidgetClass, - menuBar, args, j); - CreateMenuBarPopup(menuBar, menuName, mb); - j = 0; - XtSetArg(args[j], XtNwidth, &w); j++; - XtGetValues(mb->subMenu, args, j); - wtot += mb->textWidth = widths[nr++] = w; - mb++; - } + CreateMainMenus(mb); // put menus in bar according to description in back-end + + // size buttons to make menu bar fit, clipping menu names where necessary while(wtot > boardWidth - 40) { int wmax=0, imax=0; for(i=0; i wmax) wmax = widths[imax=i]; @@ -3960,7 +3149,8 @@ CreateMenuBar (Menu *mb, int boardWidth) XtSetArg(args[j], XtNwidth, widths[i]); j++; XtSetValues(ma[i].subMenu, args, j); } - return menuBar; + + return mainBar; } Widget @@ -4042,6 +3232,7 @@ CreatePieceMenus () whitePieceMenu = CreatePieceMenu("menuW", 0); blackPieceMenu = CreatePieceMenu("menuB", 1); + if(appData.pieceMenu) // [HGM] sweep: no idea what this was good for, but it stopped reporting button events outside the window XtRegisterGrabAction(PieceMenuPopup, True, (unsigned)(ButtonPressMask|ButtonReleaseMask), GrabModeAsync, GrabModeAsync); @@ -4140,125 +3331,23 @@ BlackClock (Widget w, XEvent *event, String *prms, Cardinal *nprms) } -/* - * If the user selects on a border boundary, return -1; if off the board, - * return -2. Otherwise map the event coordinate to the square. - */ -int -EventToSquare (int x, int limit) -{ - if (x <= 0) - return -2; - if (x < lineGap) - return -1; - x -= lineGap; - if ((x % (squareSize + lineGap)) >= squareSize) - return -1; - x /= (squareSize + lineGap); - if (x >= limit) - return -2; - return x; -} - static void do_flash_delay (unsigned long msec) { TimeDelay(msec); } -static void -drawHighlight (int file, int rank, GC gc) +void +DrawBorder (int x, int y, int type) { - int x, y; - - if (lineGap == 0) return; + GC gc = lineGC; - if (flipView) { - x = lineGap/2 + ((BOARD_WIDTH-1)-file) * - (squareSize + lineGap); - y = lineGap/2 + rank * (squareSize + lineGap); - } else { - x = lineGap/2 + file * (squareSize + lineGap); - y = lineGap/2 + ((BOARD_HEIGHT-1)-rank) * - (squareSize + lineGap); - } + if(type == 1) gc = highlineGC; else if(type == 2) gc = prelineGC; XDrawRectangle(xDisplay, xBoardWindow, gc, x, y, squareSize+lineGap, squareSize+lineGap); } -int hi1X = -1, hi1Y = -1, hi2X = -1, hi2Y = -1; -int pm1X = -1, pm1Y = -1, pm2X = -1, pm2Y = -1; - -void -SetHighlights (int fromX, int fromY, int toX, int toY) -{ - if (hi1X != fromX || hi1Y != fromY) { - if (hi1X >= 0 && hi1Y >= 0) { - drawHighlight(hi1X, hi1Y, lineGC); - } - } // [HGM] first erase both, then draw new! - if (hi2X != toX || hi2Y != toY) { - if (hi2X >= 0 && hi2Y >= 0) { - drawHighlight(hi2X, hi2Y, lineGC); - } - } - if (hi1X != fromX || hi1Y != fromY) { - if (fromX >= 0 && fromY >= 0) { - drawHighlight(fromX, fromY, highlineGC); - } - } - if (hi2X != toX || hi2Y != toY) { - if (toX >= 0 && toY >= 0) { - drawHighlight(toX, toY, highlineGC); - } - } - if(toX<0) // clearing the highlights must have damaged arrow - DrawArrowHighlight(hi1X, hi1Y, hi2X, hi2Y); // for now, redraw it (should really be cleared!) - hi1X = fromX; - hi1Y = fromY; - hi2X = toX; - hi2Y = toY; -} - -void -ClearHighlights () -{ - SetHighlights(-1, -1, -1, -1); -} - - -void -SetPremoveHighlights (int fromX, int fromY, int toX, int toY) -{ - if (pm1X != fromX || pm1Y != fromY) { - if (pm1X >= 0 && pm1Y >= 0) { - drawHighlight(pm1X, pm1Y, lineGC); - } - if (fromX >= 0 && fromY >= 0) { - drawHighlight(fromX, fromY, prelineGC); - } - } - if (pm2X != toX || pm2Y != toY) { - if (pm2X >= 0 && pm2Y >= 0) { - drawHighlight(pm2X, pm2Y, lineGC); - } - if (toX >= 0 && toY >= 0) { - drawHighlight(toX, toY, prelineGC); - } - } - pm1X = fromX; - pm1Y = fromY; - pm2X = toX; - pm2Y = toY; -} - -void -ClearPremoveHighlights () -{ - SetPremoveHighlights(-1, -1, -1, -1); -} - static int CutOutSquare (int x, int y, int *x0, int *y0, int kind) { @@ -4455,154 +3544,142 @@ ChooseDrawFunc () } } -/* [HR] determine square color depending on chess variant. */ -static int -SquareColor (int row, int column) -{ - int square_color; - - if (gameInfo.variant == VariantXiangqi) { - if (column >= 3 && column <= 5 && row >= 0 && row <= 2) { - square_color = 1; - } else if (column >= 3 && column <= 5 && row >= 7 && row <= 9) { - square_color = 0; - } else if (row <= 4) { - square_color = 0; - } else { - square_color = 1; - } - } else { - square_color = ((column + row) % 2) == 1; - } - - /* [hgm] holdings: next line makes all holdings squares light */ - if(column < BOARD_LEFT || column >= BOARD_RGHT) square_color = 1; - - return square_color; +void +DrawDot (int marker, int x, int y, int r) +{ + if(appData.monoMode) { + XFillArc(xDisplay, xBoardWindow, marker == 2 ? darkSquareGC : lightSquareGC, + x, y, r, r, 0, 64*360); + XDrawArc(xDisplay, xBoardWindow, marker == 2 ? lightSquareGC : darkSquareGC, + x, y, r, r, 0, 64*360); + } else + XFillArc(xDisplay, xBoardWindow, marker == 2 ? prelineGC : highlineGC, + x, y, r, r, 0, 64*360); } void -DrawSquare (int row, int column, ChessSquare piece, int do_flash) -{ - int square_color, x, y, direction, font_ascent, font_descent; - int i; - char string[2]; +DrawOneSquare (int x, int y, ChessSquare piece, int square_color, int marker, char *string, int align) +{ // basic front-end board-draw function: takes care of everything that can be in square: + // piece, background, coordinate/count, marker dot + int direction, font_ascent, font_descent; XCharStruct overall; DrawFunc drawfunc; - int flash_delay; - - /* Calculate delay in milliseconds (2-delays per complete flash) */ - flash_delay = 500 / appData.flashRate; - if (flipView) { - x = lineGap + ((BOARD_WIDTH-1)-column) * - (squareSize + lineGap); - y = lineGap + row * (squareSize + lineGap); - } else { - x = lineGap + column * (squareSize + lineGap); - y = lineGap + ((BOARD_HEIGHT-1)-row) * - (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 - column == BOARD_LEFT-1 || column == BOARD_RGHT - || (column == BOARD_LEFT-2 && row < BOARD_HEIGHT-gameInfo.holdingsSize) - || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) ) { - BlankSquare(x, y, 2, EmptySquare, xBoardWindow, 1); - - // [HGM] print piece counts next to holdings - string[1] = NULLCHAR; - if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) && piece > 1 ) { - string[0] = '0' + piece; - XTextExtents(countFontStruct, string, 1, &direction, - &font_ascent, &font_descent, &overall); - if (appData.monoMode) { - XDrawImageString(xDisplay, xBoardWindow, countGC, - x + squareSize - overall.width - 2, - y + font_ascent + 1, string, 1); - } else { - XDrawString(xDisplay, xBoardWindow, countGC, - x + squareSize - overall.width - 2, - y + font_ascent + 1, string, 1); - } - } - if (column == (flipView ? BOARD_RGHT : BOARD_LEFT-1) && piece > 1) { - string[0] = '0' + piece; - XTextExtents(countFontStruct, string, 1, &direction, - &font_ascent, &font_descent, &overall); - if (appData.monoMode) { - XDrawImageString(xDisplay, xBoardWindow, countGC, - x + 2, y + font_ascent + 1, string, 1); - } else { - XDrawString(xDisplay, xBoardWindow, countGC, - x + 2, y + font_ascent + 1, string, 1); - } - } + if (piece == EmptySquare) { + BlankSquare(x, y, square_color, piece, xBoardWindow, 1); } else { - if (piece == EmptySquare || appData.blindfold) { - BlankSquare(x, y, square_color, piece, xBoardWindow, 1); - } else { - drawfunc = ChooseDrawFunc(); - - if (do_flash && appData.flashCount > 0) { - for (i=0; i= BOARD_LEFT && column < BOARD_RGHT) { - string[0] = 'a' + column - BOARD_LEFT; - XTextExtents(coordFontStruct, string, 1, &direction, - &font_ascent, &font_descent, &overall); + // then draw it if (appData.monoMode) { - XDrawImageString(xDisplay, xBoardWindow, coordGC, - x + squareSize - overall.width - 2, - y + squareSize - font_descent - 1, string, 1); + XDrawImageString(xDisplay, xBoardWindow, hGC, xx, yy, string, 1); } else { - XDrawString(xDisplay, xBoardWindow, coordGC, - x + squareSize - overall.width - 2, - y + squareSize - font_descent - 1, string, 1); + XDrawString(xDisplay, xBoardWindow, hGC, xx, yy, string, 1); } } - if (appData.showCoords && column == (flipView ? BOARD_RGHT-1 : BOARD_LEFT)) { - string[0] = ONE + row; - XTextExtents(coordFontStruct, string, 1, &direction, - &font_ascent, &font_descent, &overall); - if (appData.monoMode) { - XDrawImageString(xDisplay, xBoardWindow, coordGC, - x + 2, y + font_ascent + 1, string, 1); - } else { - XDrawString(xDisplay, xBoardWindow, coordGC, - x + 2, y + font_ascent + 1, string, 1); - } - } - if(!partnerUp && marker[row][column]) { - if(appData.monoMode) { - XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? darkSquareGC : lightSquareGC, - x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); - XDrawArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? lightSquareGC : darkSquareGC, - x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); - } else - XFillArc(xDisplay, xBoardWindow, marker[row][column] == 2 ? prelineGC : highlineGC, - x + squareSize/4, y+squareSize/4, squareSize/2, squareSize/2, 0, 64*360); + + if(marker) { // print fat marker dot, if requested + DrawDot(marker, x + squareSize/4, y+squareSize/4, squareSize/2); } } +void +FlashDelay (int flash_delay) +{ + XSync(xDisplay, False); + if(flash_delay) do_flash_delay(flash_delay); +} + +double +Fraction (int x, int start, int stop) +{ + double f = ((double) x - start)/(stop - start); + if(f > 1.) f = 1.; else if(f < 0.) f = 0.; + return f; +} + +static WindowPlacement wpNew; + +void +CoDrag (Widget sh, WindowPlacement *wp) +{ + Arg args[16]; + int j=0, touch=0, fudge = 2; + GetActualPlacement(sh, wp); + if(abs(wpMain.x + wpMain.width + 2*frameX - wp->x) < fudge) touch = 1; else // right touch + if(abs(wp->x + wp->width + 2*frameX - wpMain.x) < fudge) touch = 2; else // left touch + if(abs(wpMain.y + wpMain.height + frameX + frameY - wp->y) < fudge) touch = 3; else // bottom touch + if(abs(wp->y + wp->height + frameX + frameY - wpMain.y) < fudge) touch = 4; // top touch + if(!touch ) return; // only windows that touch co-move + if(touch < 3 && wpNew.height != wpMain.height) { // left or right and height changed + int heightInc = wpNew.height - wpMain.height; + double fracTop = Fraction(wp->y, wpMain.y, wpMain.y + wpMain.height + frameX + frameY); + double fracBot = Fraction(wp->y + wp->height + frameX + frameY + 1, wpMain.y, wpMain.y + wpMain.height + frameX + frameY); + wp->y += fracTop * heightInc; + heightInc = (int) (fracBot * heightInc) - (int) (fracTop * heightInc); + if(heightInc) XtSetArg(args[j], XtNheight, wp->height + heightInc), j++; + } else if(touch > 2 && wpNew.width != wpMain.width) { // top or bottom and width changed + int widthInc = wpNew.width - wpMain.width; + double fracLeft = Fraction(wp->x, wpMain.x, wpMain.x + wpMain.width + 2*frameX); + double fracRght = Fraction(wp->x + wp->width + 2*frameX + 1, wpMain.x, wpMain.x + wpMain.width + 2*frameX); + wp->y += fracLeft * widthInc; + widthInc = (int) (fracRght * widthInc) - (int) (fracLeft * widthInc); + if(widthInc) XtSetArg(args[j], XtNwidth, wp->width + widthInc), j++; + } + wp->x += wpNew.x - wpMain.x; + wp->y += wpNew.y - wpMain.y; + if(touch == 1) wp->x += wpNew.width - wpMain.width; else + if(touch == 3) wp->y += wpNew.height - wpMain.height; + XtSetArg(args[j], XtNx, wp->x); j++; + XtSetArg(args[j], XtNy, wp->y); j++; + XtSetValues(sh, args, j); +} + +static XtIntervalId delayedDragID = 0; + +void +DragProc () +{ + GetActualPlacement(shellWidget, &wpNew); + if(wpNew.x == wpMain.x && wpNew.y == wpMain.y && // not moved + wpNew.width == wpMain.width && wpNew.height == wpMain.height) // not sized + return; // false alarm + if(EngineOutputIsUp()) CoDrag(engineOutputShell, &wpEngineOutput); + if(MoveHistoryIsUp()) CoDrag(shells[7], &wpMoveHistory); + if(EvalGraphIsUp()) CoDrag(evalGraphShell, &wpEvalGraph); + if(GameListIsUp()) CoDrag(gameListShell, &wpGameList); + wpMain = wpNew; + DrawPosition(True, NULL); + delayedDragID = 0; // now drag executed, make sure next DelayedDrag will not cancel timer event (which could now be used by other) +} + + +void +DelayedDrag () +{ + if(delayedDragID) XtRemoveTimeOut(delayedDragID); // cancel pending + delayedDragID = + XtAppAddTimeOut(appContext, 50, (XtTimerCallbackProc) DragProc, (XtPointer) 0); // and schedule new one 50 msec later +} /* Why is this needed on some versions of X? */ void @@ -4610,14 +3687,17 @@ EventProc (Widget widget, caddr_t unused, XEvent *event) { if (!XtIsRealized(widget)) return; - switch (event->type) { + case ConfigureNotify: // main window is being dragged: drag attached windows with it + if(appData.useStickyWindows) + DelayedDrag(); // as long as events keep coming in faster than 50 msec, they destroy each other + break; case Expose: if (event->xexpose.count > 0) return; /* no clipping is done */ - XDrawPosition(widget, True, NULL); + DrawPosition(True, NULL); if(twoBoards) { // [HGM] dual: draw other board in other orientation flipView = !flipView; partnerUp = !partnerUp; - XDrawPosition(widget, True, NULL); + DrawPosition(True, NULL); flipView = !flipView; partnerUp = !partnerUp; } break; @@ -4629,77 +3709,6 @@ EventProc (Widget widget, caddr_t unused, XEvent *event) } /* end why */ -void -DrawPosition (int fullRedraw, Board board) -{ - XDrawPosition(boardWidget, fullRedraw, board); -} - -/* Returns 1 if there are "too many" differences between b1 and b2 - (i.e. more than 1 move was made) */ -static int -too_many_diffs (Board b1, Board b2) -{ - int i, j; - int c = 0; - - for (i=0; i 4) /* Castling causes 4 diffs */ - return 1; - } - } - } - return 0; -} - -/* Matrix describing castling maneuvers */ -/* Row, ColRookFrom, ColKingFrom, ColRookTo, ColKingTo */ -static int castling_matrix[4][5] = { - { 0, 0, 4, 3, 2 }, /* 0-0-0, white */ - { 0, 7, 4, 5, 6 }, /* 0-0, white */ - { 7, 0, 4, 3, 2 }, /* 0-0-0, black */ - { 7, 7, 4, 5, 6 } /* 0-0, black */ -}; - -/* Checks whether castling occurred. If it did, *rrow and *rcol - are set to the destination (row,col) of the rook that moved. - - Returns 1 if castling occurred, 0 if not. - - Note: Only handles a max of 1 castling move, so be sure - to call too_many_diffs() first. - */ -static int -check_castle_draw (Board newb, Board oldb, int *rrow, int *rcol) -{ - int i, *r, j; - int match; - - /* For each type of castling... */ - for (i=0; i<4; ++i) { - r = castling_matrix[i]; - - /* Check the 4 squares involved in the castling move */ - match = 0; - for (j=1; j<=4; ++j) { - if (newb[r[0]][r[j]] == oldb[r[0]][r[j]]) { - match = 1; - break; - } - } - - if (!match) { - /* All 4 changed, so it must be a castling move */ - *rrow = r[0]; - *rcol = r[3]; - return 1; - } - } - return 0; -} - // [HGM] seekgraph: some low-level drawing routines cloned from xevalgraph void DrawSeekAxis (int x, int y, int xTo, int yTo) @@ -4734,113 +3743,12 @@ DrawSeekDot (int x, int y, int colorNr) x-squareSize/8, y-squareSize/8, squareSize/4, squareSize/4, 0, 64*360); } -static int damage[2][BOARD_RANKS][BOARD_FILES]; - -/* - * event handler for redrawing the board - */ void -XDrawPosition (Widget w, int repaint, Board board) +DrawGrid (int second) { - int i, j, do_flash; - static int lastFlipView = 0; - 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[nr]) return; - board = lastBoard[nr]; - } - if (!lastBoardValid[nr] || (nr == 0 && lastFlipView != flipView)) { - XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None)); - XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Flip View"), - args, 1); - } - - /* - * It would be simpler to clear the window with XClearWindow() - * but this causes a very distracting flicker. - */ - - 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; - - /* 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[nr], &rrow, &rcol)) { - /* Draw rook with NO flashing. King will be drawn flashing later */ - DrawSquare(rrow, rcol, board[rrow][rcol], 0); - lastBoard[nr][rrow][rcol] = board[rrow][rcol]; - } - } - - /* First pass -- Draw (newly) empty squares and repair damage. - This prevents you from having a piece show up twice while it - 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[nr][i][j] && board[i][j] == EmptySquare) - || damage[nr][i][j]) { - DrawSquare(i, j, board[i][j], 0); - 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[nr][i][j]) { - DrawSquare(i, j, board[i][j], do_flash); - } - } else { - if (lineGap > 0) XDrawSegments(xDisplay, xBoardWindow, lineGC, - twoBoards & partnerUp ? secondSegments : // [HGM] dual + second ? 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[nr][i][j] = False; - } - } - - CopyBoard(lastBoard[nr], board); - lastBoardValid[nr] = 1; - if(nr == 0) { // [HGM] dual: no highlights on second board yet - lastFlipView = flipView; - - /* Draw highlights */ - if (pm1X >= 0 && pm1Y >= 0) { - drawHighlight(pm1X, pm1Y, prelineGC); - } - if (pm2X >= 0 && pm2Y >= 0) { - drawHighlight(pm2X, pm2Y, prelineGC); - } - if (hi1X >= 0 && hi1Y >= 0) { - drawHighlight(hi1X, hi1Y, highlineGC); - } - 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(); - - XSync(xDisplay, False); } @@ -4850,7 +3758,7 @@ XDrawPosition (Widget w, int repaint, Board board) void DrawPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) { - XDrawPosition(w, True, NULL); + DrawPosition(True, NULL); } @@ -5182,7 +4090,7 @@ PromotionCallback (Widget w, XtPointer client_data, XtPointer call_data) void ErrorCallback (Widget w, XtPointer client_data, XtPointer call_data) { - errorUp = False; + dialogError = errorUp = False; XtPopdown(w = XtParent(XtParent(XtParent(w)))); XtDestroyWidget(w); if (errorExitStatus != -1) ExitEvent(errorExitStatus); @@ -5193,7 +4101,7 @@ void ErrorPopDown () { if (!errorUp) return; - errorUp = False; + dialogError = errorUp = False; XtPopdown(errorShell); XtDestroyWidget(errorShell); if (errorExitStatus != -1) ExitEvent(errorExitStatus); @@ -5216,7 +4124,7 @@ ErrorPopUp (char *title, char *label, int modal) XtSetArg(args[i], XtNtitle, title); i++; errorShell = XtCreatePopupShell("errorpopup", transientShellWidgetClass, - shellWidget, args, i); + shellUp[0] ? (dialogError = modal = TRUE, shells[0]) : shellWidget, args, i); layout = XtCreateManagedWidget(layoutName, formWidgetClass, errorShell, layoutArgs, XtNumber(layoutArgs)); @@ -5287,48 +4195,6 @@ ThawUI () frozen = 0; } -char * -ModeToWidgetName (GameMode mode) -{ - switch (mode) { - case BeginningOfGame: - if (appData.icsActive) - return "menuMode.ICS Client"; - else if (appData.noChessProgram || - *appData.cmailGameName != NULLCHAR) - return "menuMode.Edit Game"; - else - return "menuMode.Machine Black"; - case MachinePlaysBlack: - return "menuMode.Machine Black"; - case MachinePlaysWhite: - return "menuMode.Machine White"; - case AnalyzeMode: - return "menuMode.Analysis Mode"; - case AnalyzeFile: - return "menuMode.Analyze File"; - case TwoMachinesPlay: - return "menuMode.Two Machines"; - case EditGame: - return "menuMode.Edit Game"; - case PlayFromGameFile: - return "menuFile.Load Game"; - case EditPosition: - return "menuMode.Edit Position"; - case Training: - return "menuMode.Training"; - case IcsPlayingWhite: - case IcsPlayingBlack: - case IcsObserving: - case IcsIdle: - case IcsExamining: - return "menuMode.ICS Client"; - default: - case EndOfGame: - return NULL; - } -} - void ModeHighlight () { @@ -5341,13 +4207,7 @@ ModeHighlight () if (pausing != oldPausing) { oldPausing = pausing; - if (pausing) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"), - args, 1); + MarkMenuItem("Pause", pausing); if (appData.showButtonBar) { /* Always toggle, don't set. Previous code messes up when @@ -5368,33 +4228,23 @@ ModeHighlight () wname = ModeToWidgetName(oldmode); if (wname != NULL) { - XtSetArg(args[0], XtNleftBitmap, None); - XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1); + MarkMenuItem(wname, False); } wname = ModeToWidgetName(gameMode); if (wname != NULL) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1); + MarkMenuItem(wname, True); } oldmode = gameMode; - XtSetArg(args[0], XtNleftBitmap, matchMode && matchGame < appData.matchGames ? xMarkPixmap : None); - XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Machine Match"), args, 1); + MarkMenuItem("Machine Match", matchMode && matchGame < appData.matchGames); /* Maybe all the enables should be handled here, not just this one */ - XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Training"), - gameMode == Training || gameMode == PlayFromGameFile); + EnableMenuItem("Training", gameMode == Training || gameMode == PlayFromGameFile); } /* * Button/menu procedures */ -void -ResetProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ResetGameEvent(); -} - int LoadGamePopUp (FILE *f, int gameNumber, char *title) { @@ -5414,90 +4264,6 @@ LoadGamePopUp (FILE *f, int gameNumber, char *title) return LoadGame(f, gameNumber, title, FALSE); } -void -LoadGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { - Reset(FALSE, TRUE); - } - FileNamePopUp(_("Load game file name?"), "", ".pgn .game", LoadGamePopUp, "rb"); -} - -void -LoadNextGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadGame(1); -} - -void -LoadPrevGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadGame(-1); -} - -void -ReloadGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadGame(0); -} - -void -LoadNextPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadPosition(1); -} - -void -LoadPrevPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadPosition(-1); -} - -void -ReloadPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadPosition(0); -} - -void -LoadPositionProc(Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if (gameMode == AnalyzeMode || gameMode == AnalyzeFile) { - Reset(FALSE, TRUE); - } - FileNamePopUp(_("Load position file name?"), "", ".fen .epd .pos", LoadPosition, "rb"); -} - -void -SaveGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - FileNamePopUp(_("Save game file name?"), - DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"), - appData.oldSaveStyle ? ".game" : ".pgn", - SaveGame, "a"); -} - -void -SavePositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - FileNamePopUp(_("Save position file name?"), - DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"), - appData.oldSaveStyle ? ".pos" : ".fen", - SavePosition, "a"); -} - -void -ReloadCmailMsgProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ReloadCmailMsgEvent(FALSE); -} - -void -MailMoveProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - MailMoveEvent(); -} - /* this variable is shared between CopyPositionProc and SendPositionSelection */ char *selected_fen_position=NULL; @@ -5551,7 +4317,7 @@ SendPositionSelection (Widget w, Atom *selection, Atom *target, * Widget which was clicked on was, or what the click event was */ void -CopyPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +CopyPositionProc () { /* * Set both PRIMARY (the selection) and CLIPBOARD, since we don't @@ -5588,11 +4354,8 @@ PastePositionCB (Widget w, XtPointer client_data, Atom *selection, /* called when Paste Position button is pressed, * all parameters will be NULL */ -void PastePositionProc(w, event, prms, nprms) - Widget w; - XEvent *event; - String *prms; - Cardinal *nprms; +void +PastePositionProc () { XtGetSelectionValue(menuBarWidget, appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING, @@ -5684,24 +4447,6 @@ CopySomething () /* note: when called from menu all parameters are NULL, so no clue what the * Widget which was clicked on was, or what the click event was */ -void -CopyGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - int ret; - - ret = SaveGameToFile(gameCopyFilename, FALSE); - if (!ret) return; - - CopySomething(); -} - -void -CopyGameListProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if(!SaveGameListAsText(fopen(gameCopyFilename, "w"))) return; - CopySomething(); -} - /* function called when the data to Paste is ready */ static void PasteGameCB (Widget w, XtPointer client_data, Atom *selection, @@ -5725,7 +4470,7 @@ PasteGameCB (Widget w, XtPointer client_data, Atom *selection, /* called when Paste Game button is pressed, * all parameters will be NULL */ void -PasteGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +PasteGameProc () { XtGetSelectionValue(menuBarWidget, appData.pasteSelection ? XA_PRIMARY: XA_CLIPBOARD(xDisplay), XA_STRING, @@ -5742,224 +4487,9 @@ PasteGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) void -AutoSaveGame () -{ - SaveGameProc(NULL, NULL, NULL, NULL); -} - - -void -QuitProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ExitEvent(0); -} - -void -PauseProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - PauseEvent(); -} - -void -MachineBlackProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - MachineBlackEvent(); -} - -void -MachineWhiteProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - MachineWhiteEvent(); -} - -void -AnalyzeModeProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - char buf[MSG_SIZ]; - - if (!first.analysisSupport) { - snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy); - DisplayError(buf, 0); - return; - } - /* [DM] icsEngineAnalyze [HGM] This is horrible code; reverse the gameMode and isEngineAnalyze tests! */ - if (appData.icsActive) { - if (gameMode != IcsObserving) { - snprintf(buf, MSG_SIZ, _("You are not observing a game")); - DisplayError(buf, 0); - /* secure check */ - if (appData.icsEngineAnalyze) { - if (appData.debugMode) - fprintf(debugFP, _("Found unexpected active ICS engine analyze \n")); - ExitAnalyzeMode(); - ModeHighlight(); - } - return; - } - /* if enable, use want disable icsEngineAnalyze */ - if (appData.icsEngineAnalyze) { - ExitAnalyzeMode(); - ModeHighlight(); - return; - } - appData.icsEngineAnalyze = TRUE; - if (appData.debugMode) - fprintf(debugFP, _("ICS engine analyze starting... \n")); - } -#ifndef OPTIONSDIALOG - if (!appData.showThinking) - ShowThinkingProc(w,event,prms,nprms); -#endif - - AnalyzeModeEvent(); -} - -void -AnalyzeFileProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if (!first.analysisSupport) { - char buf[MSG_SIZ]; - snprintf(buf, sizeof(buf), _("%s does not support analysis"), first.tidy); - DisplayError(buf, 0); - return; - } -// Reset(FALSE, TRUE); -#ifndef OPTIONSDIALOG - if (!appData.showThinking) - ShowThinkingProc(w,event,prms,nprms); -#endif - AnalyzeFileEvent(); -// FileNamePopUp(_("File to analyze"), "", ".pgn .game", LoadGamePopUp, "rb"); - AnalysisPeriodicEvent(1); -} - -void -TwoMachinesProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - TwoMachinesEvent(); -} - -void -MatchProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - MatchEvent(2); -} - -void -IcsClientProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - IcsClientEvent(); -} - -void -EditGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - EditGameEvent(); -} - -void -EditPositionProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - EditPositionEvent(); -} - -void -TrainingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - TrainingEvent(); -} - -void -EditCommentProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[5]; - int j; - if (PopDown(1)) { // popdown succesful - j = 0; - XtSetArg(args[j], XtNleftBitmap, None); j++; - XtSetValues(XtNameToWidget(menuBarWidget, "menuEdit.Edit Comment"), args, j); - XtSetValues(XtNameToWidget(menuBarWidget, "menuView.Show Comments"), args, j); - } else // was not up - EditCommentEvent(); -} - -void -IcsInputBoxProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if (!PopDown(4)) ICSInputBoxPopUp(); -} - -void -AcceptProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - AcceptEvent(); -} - -void -DeclineProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - DeclineEvent(); -} - -void -RematchProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - RematchEvent(); -} - -void -CallFlagProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - CallFlagEvent(); -} - -void -DrawProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - DrawEvent(); -} - -void -AbortProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - AbortEvent(); -} - -void -AdjournProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - AdjournEvent(); -} - -void -ResignProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ResignEvent(); -} - -void -AdjuWhiteProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - UserAdjudicationEvent(+1); -} - -void -AdjuBlackProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - UserAdjudicationEvent(-1); -} - -void -AdjuDrawProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +QuitWrapper (Widget w, XEvent *event, String *prms, Cardinal *nprms) { - UserAdjudicationEvent(0); -} - -void -EnterKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - if (shellUp[4] == True) - ICSInputSendText(); + QuitProc(); } void @@ -6006,35 +4536,10 @@ DownKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) } void -StopObservingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - StopObservingEvent(); -} - -void -StopExaminingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - StopExaminingEvent(); -} - -void -UploadProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - UploadGameEvent(); -} - - -void -ForwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ForwardEvent(); -} - - -void -BackwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) +EnterKeyProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) { - BackwardEvent(); + if (shellUp[4] == True) + ICSInputSendText(); } void @@ -6063,452 +4568,8 @@ TempForwardProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) } void -ToStartProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ToStartEvent(); -} - -void -ToEndProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - ToEndEvent(); -} - -void -RevertProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - RevertEvent(False); -} - -void -AnnotateProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - RevertEvent(True); -} - -void -TruncateGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - TruncateGameEvent(); -} - -void -RetractMoveProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - RetractMoveEvent(); -} - -void -MoveNowProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - MoveNowEvent(); -} - -void -FlipViewProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - flipView = !flipView; - DrawPosition(True, NULL); -} - -void -PonderNextMoveProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - PonderNextMoveEvent(!appData.ponderNextMove); -#ifndef OPTIONSDIALOG - if (appData.ponderNextMove) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Ponder Next Move"), - args, 1); -#endif -} - -#ifndef OPTIONSDIALOG -void -AlwaysQueenProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen; - - if (appData.alwaysPromoteToQueen) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"), - args, 1); -} - -void -AnimateDraggingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.animateDragging = !appData.animateDragging; - - if (appData.animateDragging) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - CreateAnimVars(); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Dragging"), - args, 1); -} - -void -AnimateMovingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.animate = !appData.animate; - - if (appData.animate) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - CreateAnimVars(); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Animate Moving"), - args, 1); -} - -void -AutoflagProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.autoCallFlag = !appData.autoCallFlag; - - if (appData.autoCallFlag) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"), - args, 1); -} - -void -AutoflipProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.autoFlipView = !appData.autoFlipView; - - if (appData.autoFlipView) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flip View"), - args, 1); -} - -void -BlindfoldProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.blindfold = !appData.blindfold; - - if (appData.blindfold) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Blindfold"), - args, 1); - - DrawPosition(True, NULL); -} - -void -TestLegalityProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.testLegality = !appData.testLegality; - - if (appData.testLegality) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Test Legality"), - args, 1); -} - - -void -FlashMovesProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - if (appData.flashCount == 0) { - appData.flashCount = 3; - } else { - appData.flashCount = -appData.flashCount; - } - - if (appData.flashCount > 0) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flash Moves"), - args, 1); -} - -#if HIGHDRAG -void -HighlightDraggingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.highlightDragging = !appData.highlightDragging; - - if (appData.highlightDragging) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Dragging"), args, 1); -} -#endif - -void -HighlightLastMoveProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.highlightLastMove = !appData.highlightLastMove; - - if (appData.highlightLastMove) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Highlight Last Move"), args, 1); -} - -void -HighlightArrowProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.highlightMoveWithArrow = !appData.highlightMoveWithArrow; - - if (appData.highlightMoveWithArrow) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Arrow"), args, 1); -} - -#if 0 -void -IcsAlarmProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.icsAlarm = !appData.icsAlarm; - - if (appData.icsAlarm) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.ICS Alarm"), args, 1); -} -#endif - -void -MoveSoundProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.ringBellAfterMoves = !appData.ringBellAfterMoves; - - if (appData.ringBellAfterMoves) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Move Sound"), - args, 1); -} - -void -OneClickProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.oneClick = !appData.oneClick; - - if (appData.oneClick) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.OneClick"), - args, 1); -} - -void -PeriodicUpdatesProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - PeriodicUpdatesEvent(!appData.periodicUpdates); - - if (appData.periodicUpdates) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Periodic Updates"), - args, 1); -} - -void -PopupExitMessageProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.popupExitMessage = !appData.popupExitMessage; - - if (appData.popupExitMessage) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Popup Exit Message"), args, 1); -} - -void -PopupMoveErrorsProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.popupMoveErrors = !appData.popupMoveErrors; - - if (appData.popupMoveErrors) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Popup Move Errors"), - args, 1); -} - -#if 0 -void -PremoveProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.premove = !appData.premove; - - if (appData.premove) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, - "menuOptions.Premove"), args, 1); -} -#endif - -void -ShowCoordsProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.showCoords = !appData.showCoords; - - if (appData.showCoords) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"), - args, 1); - - DrawPosition(True, NULL); -} - -void -ShowThinkingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent - ShowThinkingEvent(); -} - -void -HideThinkingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - appData.hideThinkingFromHuman = !appData.hideThinkingFromHuman; // [HGM] thinking: tken out of ShowThinkingEvent - ShowThinkingEvent(); - - if (appData.hideThinkingFromHuman) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Hide Thinking"), - args, 1); -} -#endif - -void -SaveOnExitProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - Arg args[16]; - - saveSettingsOnExit = !saveSettingsOnExit; - - if (saveSettingsOnExit) { - XtSetArg(args[0], XtNleftBitmap, xMarkPixmap); - } else { - XtSetArg(args[0], XtNleftBitmap, None); - } - XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Save Settings on Exit"), - args, 1); -} - -void -SaveSettingsProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - SaveSettings(settingsFileName); -} - -void -InfoProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - char buf[MSG_SIZ]; - snprintf(buf, sizeof(buf), "xterm -e info --directory %s --directory . -f %s &", - INFODIR, INFOFILE); - system(buf); -} - -void -ManProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ +ManInner (Widget w, XEvent *event, String *prms, Cardinal *nprms) +{ // called as key binding char buf[MSG_SIZ]; String name; if (nprms && *nprms > 0) @@ -6520,56 +4581,6 @@ ManProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) } void -HintProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - HintEvent(); -} - -void -BookProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - BookEvent(); -} - -void -AboutProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - char buf[MSG_SIZ]; -#if ZIPPY - char *zippy = _(" (with Zippy code)"); -#else - char *zippy = ""; -#endif - snprintf(buf, sizeof(buf), -_("%s%s\n\n" -"Copyright 1991 Digital Equipment Corporation\n" -"Enhancements Copyright 1992-2009 Free Software Foundation\n" -"Enhancements Copyright 2005 Alessandro Scotti\n\n" -"%s is free software and carries NO WARRANTY;" -"see the file COPYING for more information."), - programVersion, zippy, PACKAGE); - ErrorPopUp(_("About XBoard"), buf, FALSE); -} - -void -DebugProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - appData.debugMode = !appData.debugMode; -} - -void -AboutGameProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - AboutGameEvent(); -} - -void -NothingProc (Widget w, XEvent *event, String *prms, Cardinal *nprms) -{ - return; -} - -void DisplayMessage (char *message, char *extMessage) { /* display a message in the message widget */ @@ -7304,7 +5315,7 @@ StartChildProcess (char *cmdLine, char *dir, ProcRef *pr) char buf[MSG_SIZ]; if (appData.debugMode) { - fprintf(stderr, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine); + fprintf(debugFP, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine); } /* We do NOT feed the cmdLine to the shell; we just @@ -7675,18 +5686,7 @@ OutputToProcessDelayed (ProcRef pr, char *message, int count, int *outError, lon return outCount; } -/**** Animation code by Hugh Fisher, DCS, ANU. - - Known problem: if a window overlapping the board is - moved away while a piece is being animated underneath, - the newly exposed area won't be updated properly. - I can live with this. - - Known problem: if you look carefully at the animation - of pieces in mono mode, they are being drawn as solid - shapes without interior detail while moving. Fixing - this would be a major complication for minimal return. -****/ +/**** Animation code by Hugh Fisher, DCS, ANU. ****/ /* Masks for XPM pieces. Black and white pieces can have different shapes, but in the interest of retaining my @@ -7695,6 +5695,8 @@ OutputToProcessDelayed (ProcRef pr, char *message, int count, int *outError, lon background square colors/images. */ static int xpmDone = 0; +static Pixmap animBufs[3*NrOfAnims]; // newBuf, saveBuf +static GC animGCs[3*NrOfAnims]; // blitGC, pieceGC, outlineGC; static void CreateAnimMasks (int pieceDepth) @@ -7775,15 +5777,16 @@ CreateAnimMasks (int pieceDepth) } static void -InitAnimState (AnimState *anim, XWindowAttributes *info) +InitAnimState (AnimNr anr, XWindowAttributes *info) { XtGCMask mask; XGCValues values; /* Each buffer is square size, same depth as window */ - anim->saveBuf = XCreatePixmap(xDisplay, xBoardWindow, + animBufs[anr+4] = xBoardWindow; + animBufs[anr+2] = XCreatePixmap(xDisplay, xBoardWindow, squareSize, squareSize, info->depth); - anim->newBuf = XCreatePixmap(xDisplay, xBoardWindow, + animBufs[anr] = XCreatePixmap(xDisplay, xBoardWindow, squareSize, squareSize, info->depth); /* Create a plain GC for blitting */ @@ -7794,17 +5797,17 @@ InitAnimState (AnimState *anim, XWindowAttributes *info) values.function = GXcopy; values.plane_mask = AllPlanes; values.graphics_exposures = False; - anim->blitGC = XCreateGC(xDisplay, xBoardWindow, mask, &values); + animGCs[anr] = XCreateGC(xDisplay, xBoardWindow, mask, &values); /* Piece will be copied from an existing context at the start of each new animation/drag. */ - anim->pieceGC = XCreateGC(xDisplay, xBoardWindow, 0, &values); + animGCs[anr+2] = XCreateGC(xDisplay, xBoardWindow, 0, &values); /* Outline will be a read-only copy of an existing */ - anim->outlineGC = None; + animGCs[anr+4] = None; } -static void +void CreateAnimVars () { XWindowAttributes info; @@ -7813,8 +5816,8 @@ CreateAnimVars () if(xpmDone) oldVariant = gameInfo.variant; // first time pieces might not be created yet XGetWindowAttributes(xDisplay, xBoardWindow, &info); - InitAnimState(&game, &info); - InitAnimState(&player, &info); + InitAnimState(Game, &info); + InitAnimState(Player, &info); /* For XPM pieces, we need bitmaps to use as masks. */ if (useImages) @@ -7833,7 +5836,7 @@ FrameAlarm (int sig) signal(SIGALRM, FrameAlarm); } -static void +void FrameDelay (int time) { struct itimerval delay; @@ -7857,7 +5860,7 @@ FrameDelay (int time) #else -static void +void FrameDelay (int time) { XSync(xDisplay, False); @@ -7867,159 +5870,6 @@ FrameDelay (int time) #endif -void -DoSleep (int n) -{ - FrameDelay(n); -} - -/* Convert board position to corner of screen rect and color */ - -static void -ScreenSquare (int column, int row, XPoint *pt, int *color) -{ - if (flipView) { - pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap); - pt->y = lineGap + row * (squareSize + lineGap); - } else { - pt->x = lineGap + column * (squareSize + lineGap); - pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap); - } - *color = SquareColor(row, column); -} - -/* Convert window coords to square */ - -static void -BoardSquare (int x, int y, int *column, int *row) -{ - *column = EventToSquare(x, BOARD_WIDTH); - if (flipView && *column >= 0) - *column = BOARD_WIDTH - 1 - *column; - *row = EventToSquare(y, BOARD_HEIGHT); - if (!flipView && *row >= 0) - *row = BOARD_HEIGHT - 1 - *row; -} - -/* Utilities */ - -#undef Max /* just in case */ -#undef Min -#define Max(a, b) ((a) > (b) ? (a) : (b)) -#define Min(a, b) ((a) < (b) ? (a) : (b)) - -static void -SetRect (XRectangle *rect, int x, int y, int width, int height) -{ - rect->x = x; - rect->y = y; - rect->width = width; - rect->height = height; -} - -/* Test if two frames overlap. If they do, return - intersection rect within old and location of - that rect within new. */ - -static Boolean -Intersect ( XPoint *old, XPoint *new, int size, XRectangle *area, XPoint *pt) -{ - if (old->x > new->x + size || new->x > old->x + size || - old->y > new->y + size || new->y > old->y + size) { - return False; - } else { - SetRect(area, Max(new->x - old->x, 0), Max(new->y - old->y, 0), - size - abs(old->x - new->x), size - abs(old->y - new->y)); - pt->x = Max(old->x - new->x, 0); - pt->y = Max(old->y - new->y, 0); - return True; - } -} - -/* For two overlapping frames, return the rect(s) - in the old that do not intersect with the new. */ - -static void -CalcUpdateRects (XPoint *old, XPoint *new, int size, XRectangle update[], int *nUpdates) -{ - int count; - - /* If old = new (shouldn't happen) then nothing to draw */ - if (old->x == new->x && old->y == new->y) { - *nUpdates = 0; - return; - } - /* Work out what bits overlap. Since we know the rects - are the same size we don't need a full intersect calc. */ - count = 0; - /* Top or bottom edge? */ - if (new->y > old->y) { - SetRect(&(update[count]), old->x, old->y, size, new->y - old->y); - count ++; - } else if (old->y > new->y) { - SetRect(&(update[count]), old->x, old->y + size - (old->y - new->y), - size, old->y - new->y); - count ++; - } - /* Left or right edge - don't overlap any update calculated above. */ - if (new->x > old->x) { - SetRect(&(update[count]), old->x, Max(new->y, old->y), - new->x - old->x, size - abs(new->y - old->y)); - count ++; - } else if (old->x > new->x) { - SetRect(&(update[count]), new->x + size, Max(new->y, old->y), - old->x - new->x, size - abs(new->y - old->y)); - count ++; - } - /* Done */ - *nUpdates = count; -} - -/* Generate a series of frame coords from start->mid->finish. - The movement rate doubles until the half way point is - reached, then halves back down to the final destination, - which gives a nice slow in/out effect. The algorithmn - may seem to generate too many intermediates for short - moves, but remember that the purpose is to attract the - viewers attention to the piece about to be moved and - then to where it ends up. Too few frames would be less - noticeable. */ - -static void -Tween (XPoint *start, XPoint *mid, XPoint *finish, int factor, XPoint frames[], int *nFrames) -{ - int fraction, n, count; - - count = 0; - - /* Slow in, stepping 1/16th, then 1/8th, ... */ - fraction = 1; - for (n = 0; n < factor; n++) - fraction *= 2; - for (n = 0; n < factor; n++) { - frames[count].x = start->x + (mid->x - start->x) / fraction; - frames[count].y = start->y + (mid->y - start->y) / fraction; - count ++; - fraction = fraction / 2; - } - - /* Midpoint */ - frames[count] = *mid; - count ++; - - /* Slow out, stepping 1/2, then 1/4, ... */ - fraction = 2; - for (n = 0; n < factor; n++) { - frames[count].x = finish->x - (finish->x - mid->x) / fraction; - frames[count].y = finish->y - (finish->y - mid->y) / fraction; - count ++; - fraction = fraction * 2; - } - *nFrames = count; -} - -/* Draw a piece on the screen without disturbing what's there */ - static void SelectGCMask (ChessSquare piece, GC *clip, GC *outline, Pixmap *mask) { @@ -8088,334 +5938,32 @@ OverlayPiece (ChessSquare piece, GC clip, GC outline, Drawable dest) } } -/* Animate the movement of a single piece */ - -static void -BeginAnimation (AnimState *anim, ChessSquare piece, int startColor, XPoint *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; - - /* The piece will be drawn using its own bitmap as a matte */ - SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask); - XSetClipMask(xDisplay, anim->pieceGC, mask); -} - -static void -AnimationFrame (AnimState *anim, XPoint *frame, ChessSquare piece) -{ - XRectangle updates[4]; - XRectangle overlap; - XPoint pt; - int count, i; - - /* Save what we are about to draw into the new buffer */ - XCopyArea(xDisplay, xBoardWindow, anim->newBuf, anim->blitGC, - frame->x, frame->y, squareSize, squareSize, - 0, 0); - - /* Erase bits of the previous frame */ - if (Intersect(&anim->prevFrame, frame, squareSize, &overlap, &pt)) { - /* Where the new frame overlapped the previous, - the contents in newBuf are wrong. */ - XCopyArea(xDisplay, anim->saveBuf, anim->newBuf, anim->blitGC, - overlap.x, overlap.y, - overlap.width, overlap.height, - pt.x, pt.y); - /* Repaint the areas in the old that don't overlap new */ - CalcUpdateRects(&anim->prevFrame, frame, squareSize, updates, &count); - for (i = 0; i < count; i++) - XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC, - updates[i].x - anim->prevFrame.x, - updates[i].y - anim->prevFrame.y, - updates[i].width, updates[i].height, - updates[i].x, updates[i].y); - } else { - /* Easy when no overlap */ - XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC, - 0, 0, squareSize, squareSize, - anim->prevFrame.x, anim->prevFrame.y); - } - - /* Save this frame for next time round */ - XCopyArea(xDisplay, anim->newBuf, anim->saveBuf, anim->blitGC, - 0, 0, squareSize, squareSize, - 0, 0); - anim->prevFrame = *frame; - - /* Draw piece over original screen contents, not current, - and copy entire rect. Wipes out overlapping piece images. */ - OverlayPiece(piece, anim->pieceGC, anim->outlineGC, anim->newBuf); - XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC, - 0, 0, squareSize, squareSize, - frame->x, frame->y); -} - -static void -EndAnimation (AnimState *anim, XPoint *finish) -{ - XRectangle updates[4]; - XRectangle overlap; - XPoint pt; - int count, i; - - /* The main code will redraw the final square, so we - only need to erase the bits that don't overlap. */ - if (Intersect(&anim->prevFrame, finish, squareSize, &overlap, &pt)) { - CalcUpdateRects(&anim->prevFrame, finish, squareSize, updates, &count); - for (i = 0; i < count; i++) - XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC, - updates[i].x - anim->prevFrame.x, - updates[i].y - anim->prevFrame.y, - updates[i].width, updates[i].height, - updates[i].x, updates[i].y); - } else { - XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC, - 0, 0, squareSize, squareSize, - anim->prevFrame.x, anim->prevFrame.y); - } -} - -static void -FrameSequence (AnimState *anim, ChessSquare piece, int startColor, XPoint *start, XPoint *finish, XPoint frames[], int nFrames) -{ - int n; - - BeginAnimation(anim, piece, startColor, start); - for (n = 0; n < nFrames; n++) { - AnimationFrame(anim, &(frames[n]), piece); - FrameDelay(appData.animSpeed); - } - EndAnimation(anim, finish); -} - void -AnimateAtomicCapture (Board board, int fromX, int fromY, int toX, int toY) +InsertPiece (AnimNr anr, ChessSquare piece) { - int i, x, y; - ChessSquare piece = board[fromY][toY]; - board[fromY][toY] = EmptySquare; - DrawPosition(FALSE, board); - if (flipView) { - x = lineGap + ((BOARD_WIDTH-1)-toX) * (squareSize + lineGap); - y = lineGap + toY * (squareSize + lineGap); - } else { - x = lineGap + toX * (squareSize + lineGap); - y = lineGap + ((BOARD_HEIGHT-1)-toY) * (squareSize + lineGap); - } - for(i=1; i<4*kFactor; i++) { - int r = squareSize * 9 * i/(20*kFactor - 5); - XFillArc(xDisplay, xBoardWindow, highlineGC, - x + squareSize/2 - r, y+squareSize/2 - r, 2*r, 2*r, 0, 64*360); - FrameDelay(appData.animSpeed); - } - board[fromY][toY] = piece; + OverlayPiece(piece, animGCs[anr+2], animGCs[anr+4], animBufs[anr]); } -/* Main control logic for deciding what to animate and how */ - void -AnimateMove (Board board, int fromX, int fromY, int toX, int toY) +DrawBlank (AnimNr anr, int x, int y, int startColor) { - ChessSquare piece; - int hop; - XPoint start, finish, mid; - XPoint frames[kFactor * 2 + 1]; - int nFrames, startColor, endColor; - - /* Are we animating? */ - if (!appData.animate || appData.blindfold) - return; - - 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; - piece = board[fromY][fromX]; - if (piece >= EmptySquare) return; - -#if DONT_HOP - hop = FALSE; -#else - hop = abs(fromX-toX) == 1 && abs(fromY-toY) == 2 || abs(fromX-toX) == 2 && abs(fromY-toY) == 1; -#endif - - if (appData.debugMode) { - fprintf(debugFP, hop ? _("AnimateMove: piece %d hops from %d,%d to %d,%d \n") : - _("AnimateMove: piece %d slides from %d,%d to %d,%d \n"), - piece, fromX, fromY, toX, toY); } - - ScreenSquare(fromX, fromY, &start, &startColor); - ScreenSquare(toX, toY, &finish, &endColor); - - if (hop) { - /* Knight: make straight movement then diagonal */ - if (abs(toY - fromY) < abs(toX - fromX)) { - mid.x = start.x + (finish.x - start.x) / 2; - mid.y = start.y; - } else { - mid.x = start.x; - mid.y = start.y + (finish.y - start.y) / 2; - } - } else { - mid.x = start.x + (finish.x - start.x) / 2; - mid.y = start.y + (finish.y - start.y) / 2; - } - - /* Don't use as many frames for very short moves */ - if (abs(toY - fromY) + abs(toX - fromX) <= 2) - Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames); - else - Tween(&start, &mid, &finish, kFactor, frames, &nFrames); - FrameSequence(&game, piece, startColor, &start, &finish, frames, nFrames); - if(Explode(board, fromX, fromY, toX, toY)) { // mark as damaged - int i,j; - for(i=0; i= 0 && player.dragPiece < EmptySquare) { - player.dragActive = True; - BeginAnimation(&player, player.dragPiece, color, &corner); - /* Mark this square as needing to be redrawn. Note that - we don't remove the piece though, since logically (ie - as seen by opponent) the move hasn't been made yet. */ - if(boardX == BOARD_RGHT+1 && PieceForSquare(boardX-1, boardY) > 1 || - boardX == BOARD_LEFT-2 && PieceForSquare(boardX+1, boardY) > 1) - XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC, - corner.x, corner.y, squareSize, squareSize, - 0, 0); // [HGM] zh: unstack in stead of grab - if(gatingPiece != EmptySquare) { - /* Kludge alert: When gating we want the introduced - piece to appear on the from square. To generate an - image of it, we draw it on the board, copy the image, - and draw the original piece again. */ - ChessSquare piece = boards[currentMove][boardY][boardX]; - DrawSquare(boardY, boardX, gatingPiece, 0); - XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC, - corner.x, corner.y, squareSize, squareSize, 0, 0); - DrawSquare(boardY, boardX, piece, 0); - } - damage[0][boardY][boardX] = True; - } else { - player.dragActive = False; - } + XCopyArea(xDisplay, animBufs[anr+srcBuf], animBufs[anr+destBuf], animGCs[anr], + srcX, srcY, width, height, destX, destY); } void -ChangeDragPiece (ChessSquare piece) +SetDragPiece (AnimNr anr, ChessSquare piece) { Pixmap mask; - player.dragPiece = piece; /* The piece will be drawn using its own bitmap as a matte */ - SelectGCMask(piece, &player.pieceGC, &player.outlineGC, &mask); - XSetClipMask(xDisplay, player.pieceGC, mask); -} - -static void -DragPieceMove (int x, int y) -{ - XPoint corner; - - /* Are we animating? */ - if (!appData.animateDragging || appData.blindfold) - return; - - /* Sanity check */ - if (! player.dragActive) - return; - /* Move piece, maintaining same relative position - of mouse within square */ - corner.x = x - player.mouseDelta.x; - corner.y = y - player.mouseDelta.y; - AnimationFrame(&player, &corner, player.dragPiece); -#if HIGHDRAG*0 - if (appData.highlightDragging) { - int boardX, boardY; - BoardSquare(x, y, &boardX, &boardY); - SetHighlights(fromX, fromY, boardX, boardY); - } -#endif -} - -void -DragPieceEnd (int x, int y) -{ - int boardX, boardY, color; - XPoint corner; - - /* Are we animating? */ - if (!appData.animateDragging || appData.blindfold) - return; - - /* Sanity check */ - if (! player.dragActive) - return; - /* Last frame in sequence is square piece is - placed on, which may not match mouse exactly. */ - BoardSquare(x, y, &boardX, &boardY); - ScreenSquare(boardX, boardY, &corner, &color); - EndAnimation(&player, &corner); - - /* Be sure end square is redrawn */ - damage[0][boardY][boardX] = True; - - /* This prevents weird things happening with fast successive - clicks which on my Sun at least can cause motion events - without corresponding press/release. */ - player.dragActive = False; -} - -/* Handle expose event while piece being dragged */ - -static void -DrawDragPiece () -{ - if (!player.dragActive || appData.blindfold) - return; - - /* What we're doing: logically, the move hasn't been made yet, - so the piece is still in it's original square. But visually - it's being dragged around the board. So we erase the square - that the piece is on and draw it at the last known drag point. */ - BlankSquare(player.startSquare.x, player.startSquare.y, - player.startColor, EmptySquare, xBoardWindow, 1); - AnimationFrame(&player, &player.prevFrame, player.dragPiece); - damage[0][player.startBoardY][player.startBoardX] = TRUE; + SelectGCMask(piece, &animGCs[anr+2], &animGCs[anr+4], &mask); + XSetClipMask(xDisplay, animGCs[anr+2], mask); } #include @@ -8458,209 +6006,14 @@ NotifyFrontendLogin () /* [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) +DrawPolygon (Pnt arrow[], int nr) { - XPoint arrow[8]; - 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); - if(appData.monoMode) arrow[7] = arrow[0], XDrawLines(xDisplay, xBoardWindow, darkSquareGC, arrow, 8, CoordModeOrigin); -// Polygon( hdc, arrow, 7 ); -} - -void -ArrowDamage (int s_col, int s_row, int d_col, int d_row) -{ - int hor, vert, i; - 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; - } -} - -/* [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; - - 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 ); - ArrowDamage(s_col, s_row, d_col, d_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); + XPoint pts[10]; + int i; + for(i=0; i<10; i++) pts[i].x = arrow[i].x, pts[i].y = arrow[i].y; + XFillPolygon(xDisplay, xBoardWindow, highlineGC, pts, nr, Nonconvex, CoordModeOrigin); + if(appData.monoMode) arrow[nr] = arrow[0], XDrawLines(xDisplay, xBoardWindow, darkSquareGC, pts, nr+1, CoordModeOrigin); } void