moved show/hide thinking procs to gtk
[xboard.git] / xboard.c
index 39ed7de..9ad61d2 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -235,6 +235,13 @@ typedef struct {
     MenuItem *mi;
 } Menu;
 
+typedef struct {
+    char *name;
+    gboolean value;
+} Enables;
+
+
+
 int main P((int argc, char **argv));
 RETSIGTYPE CmailSigHandler P((int sig));
 RETSIGTYPE IntSigHandler P((int sig));
@@ -306,18 +313,10 @@ void SavePositionProc P((Widget w, XEvent *event,
 void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void ReloadCmailMsgProc 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 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));
@@ -326,32 +325,7 @@ 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 EnterKeyProc 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 BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void 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,
@@ -369,9 +343,6 @@ void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void BlindfoldProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void FlashMovesProc P((Widget w, XEvent *event, String *prms,
                       Cardinal *nprms));
-void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void GetMoveListProc P((Widget w, XEvent *event, String *prms,
-                       Cardinal *nprms));
 void HighlightDraggingProc P((Widget w, XEvent *event, String *prms,
                              Cardinal *nprms));
 void HighlightLastMoveProc P((Widget w, XEvent *event, String *prms,
@@ -390,16 +361,8 @@ void PopupExitMessageProc P((Widget w, XEvent *event, String *prms,
                             Cardinal *nprms));
 void PremoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
-void 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 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 DebugProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
@@ -431,6 +394,8 @@ void UciPopDown P(());
 void TimeControlPopDown P(());
 void NewVariantPopDown P(());
 void SettingsPopDown P(());
+void SetMenuEnables P((Enables *enab));
+
 /*
 * XBoard depends on Xt R4 or higher
 */
@@ -531,6 +496,157 @@ static Pixmap xpmMask[BlackKing + 1];
 
 SizeDefaults sizeDefaults[] = SIZE_DEFAULTS;
 
+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 },
+#ifndef ZIPPY
+    { "menuHelp.Hint", False },
+    { "menuHelp.Book", False },
+    { "menuStep.Move Now", False },
+    { "menuOptions.Periodic Updates", False },
+    { "menuOptions.Hide Thinking", False },
+    { "menuOptions.Ponder Next Move", False },
+#endif
+    { 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.ICS Client", False },
+    { "menuMode.ICS Input Box", False },
+    { "Action", False },
+    { "menuStep.Revert", False },
+    { "menuStep.Move Now", False },
+    { "menuStep.Retract Move", False },
+    { "menuOptions.Auto Comment", False },
+    { "menuOptions.Auto Flag", False },
+    { "menuOptions.Auto Flip View", False },
+    { "menuOptions.Auto Observe", False },
+    { "menuOptions.Auto Raise Board", False },
+    { "menuOptions.Get Move List", False },
+    { "menuOptions.ICS Alarm", False },
+    { "menuOptions.Move Sound", False },
+    { "menuOptions.Quiet Play", False },
+    { "menuOptions.Hide Thinking", False },
+    { "menuOptions.Periodic Updates", False },
+    { "menuOptions.Ponder Next Move", False },
+    { "menuHelp.Hint", False },
+    { "menuHelp.Book", False },
+    { NULL, False }
+};
+
+Enables gnuEnables[] = {
+    { "menuMode.ICS Client", False },
+    { "menuMode.ICS Input Box", False },
+    { "menuAction.Accept", False },
+    { "menuAction.Decline", False },
+    { "menuAction.Rematch", False },
+    { "menuAction.Adjourn", False },
+    { "menuAction.Stop Examining", False },
+    { "menuAction.Stop Observing", False },
+    { "menuStep.Revert", False },
+    { "menuOptions.Auto Comment", False },
+    { "menuOptions.Auto Observe", False },
+    { "menuOptions.Auto Raise Board", False },
+    { "menuOptions.Get Move List", False },
+    { "menuOptions.Premove", False },
+    { "menuOptions.Quiet Play", False },
+
+    /* 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 },
+    { 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 },
+  { "menuStep.Forward", False },
+  { "menuStep.Backward", False },
+  { "menuStep.Forward to End", False },
+  { "menuStep.Back to Start", False },
+  { "menuStep.Move Now", False },
+  { "menuStep.Truncate Game", False },
+  { NULL, False }
+};
+
+Enables trainingOffEnables[] = {
+  { "menuMode.Edit Comment", True },
+  { "menuMode.Pause", True },
+  { "menuStep.Forward", True },
+  { "menuStep.Backward", True },
+  { "menuStep.Forward to End", True },
+  { "menuStep.Back to Start", True },
+  { "menuStep.Move Now", True },
+  { "menuStep.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 },
+  { "menuFile.Paste Game", False },
+  { "menuFile.Load Position", False },
+  { "menuFile.Load Next Position", False },
+  { "menuFile.Load Previous Position", False },
+  { "menuFile.Reload Same Position", False },
+  { "menuFile.Paste Position", False },
+  { "menuMode.Machine White", False },
+  { "menuMode.Machine Black", False },
+  { "menuMode.Two Machines", False },
+  { "menuStep.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 },
+  { "menuFile.Paste Game", True },
+  { "menuFile.Load Position", True },
+  { "menuFile.Load Next Position", True },
+  { "menuFile.Load Previous Position", True },
+  { "menuFile.Reload Same Position", True },
+  { "menuFile.Paste Position", True },
+  { "menuMode.Machine White", True },
+  { "menuMode.Machine Black", True },
+  { "menuMode.Two Machines", True },
+  { "menuStep.Retract Move", True },
+  { NULL, False }
+};
+
+
+
 MenuItem fileMenu[] = {
     {N_("New Shuffle Game ..."), ShuffleMenuProc},
     {N_("New Variant ..."), NewVariantProc},      // [HGM] variant: not functional yet
@@ -556,12 +672,12 @@ MenuItem fileMenu[] = {
 };
 
 MenuItem modeMenu[] = {
-    {N_("Machine White"), MachineWhiteProc},
-    {N_("Machine Black"), MachineBlackProc},
-    {N_("Two Machines"), TwoMachinesProc},
+  //    {N_("Machine White"), MachineWhiteProc},
+  //    {N_("Machine Black"), MachineBlackProc},
+  //    {N_("Two Machines"), TwoMachinesProc},
     {N_("Analysis Mode"), AnalyzeModeProc},
     {N_("Analyze File"), AnalyzeFileProc },
-    {N_("ICS Client"), IcsClientProc},
+    //    {N_("ICS Client"), IcsClientProc},
     {N_("Edit Game"), EditGameProc},
     {N_("Edit Position"), EditPositionProc},
     {N_("Training"), TrainingProc},
@@ -569,7 +685,7 @@ MenuItem modeMenu[] = {
     {N_("Show Engine Output"), EngineOutputProc},
     {N_("Show Evaluation Graph"), NothingProc}, // [HGM] evalgr: not functional yet
     {N_("Show Game List"), ShowGameListProc},
-    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
+    //    {"Show Move History", HistoryShowProc}, // [HGM] hist: activate 4.2.7 code
     {"----", NothingProc},
     {N_("Edit Tags"), EditTagsProc},
     {N_("Edit Comment"), EditCommentProc},
@@ -577,42 +693,9 @@ MenuItem modeMenu[] = {
     {NULL, NULL}
 };
 
-MenuItem actionMenu[] = {
-    {N_("Accept"), AcceptProc},
-    {N_("Decline"), DeclineProc},
-    {N_("Rematch"), RematchProc},
-    {"----", NothingProc},
-    {N_("Call Flag"), CallFlagProc},
-    {N_("Draw"), DrawProc},
-    {N_("Adjourn"), AdjournProc},
-    {N_("Abort"), AbortProc},
-    {N_("Resign"), ResignProc},
-    {"----", NothingProc},
-    {N_("Stop Observing"), StopObservingProc},
-    {N_("Stop Examining"), StopExaminingProc},
-    {"----", NothingProc},
-    {N_("Adjudicate to White"), AdjuWhiteProc},
-    {N_("Adjudicate to Black"), AdjuBlackProc},
-    {N_("Adjudicate Draw"), AdjuDrawProc},
-    {NULL, NULL}
-};
-
-MenuItem stepMenu[] = {
-    {N_("Backward"), BackwardProc},
-    {N_("Forward"), ForwardProc},
-    {N_("Back to Start"), ToStartProc},
-    {N_("Forward to End"), ToEndProc},
-    {N_("Revert"), RevertProc},
-    {N_("Truncate Game"), TruncateGameProc},
-    {"----", NothingProc},
-    {N_("Move Now"), MoveNowProc},
-    {N_("Retract Move"), RetractMoveProc},
-    {NULL, NULL}
-};
-
 MenuItem optionsMenu[] = {
-    {N_("Flip View"), FlipViewProc},
-    {"----", NothingProc},
+  //    {N_("Flip View"), FlipViewProc},
+  //    {"----", NothingProc},
     {N_("Adjudications ..."), EngineMenuProc},
     {N_("General Settings ..."), UciMenuProc},
     {N_("Engine #1 Settings ..."), FirstSettingsProc},
@@ -630,7 +713,7 @@ MenuItem optionsMenu[] = {
     {N_("Auto Save"), AutosaveProc},
     {N_("Blindfold"), BlindfoldProc},
     {N_("Flash Moves"), FlashMovesProc},
-    {N_("Get Move List"), GetMoveListProc},
+ //    {N_("Get Move List"), GetMoveListProc},
 #if HIGHDRAG
     {N_("Highlight Dragging"), HighlightDraggingProc},
 #endif
@@ -644,38 +727,25 @@ MenuItem optionsMenu[] = {
     {N_("Popup Move Errors"), PopupMoveErrorsProc},
     {N_("Premove"), PremoveProc},
     {N_("Quiet Play"), QuietPlayProc},
-    {N_("Hide Thinking"), HideThinkingProc},
+    //    {N_("Hide Thinking"), HideThinkingProc},
     {N_("Test Legality"), TestLegalityProc},
     {NULL, NULL}
 };
 
-MenuItem helpMenu[] = {
-    {N_("Info XBoard"), InfoProc},
-    {N_("Man XBoard"), ManProc},
-    {"----", NothingProc},
-    {N_("Hint"), HintProc},
-    {N_("Book"), BookProc},
-    {"----", NothingProc},
-    {NULL, NULL}
-};
-
 Menu menuBar[] = {
     {N_("File"), fileMenu},
     {N_("Mode"), modeMenu},
-    {N_("Action"), actionMenu},
-    {N_("Step"), stepMenu},
     {N_("Options"), optionsMenu},
-    {N_("Help"), helpMenu},
     {NULL, NULL}
 };
 
 #define PAUSE_BUTTON N_("P")
 MenuItem buttonBar[] = {
-    {"<<", ToStartProc},
-    {"<", BackwardProc},
+  //    {"<<", ToStartProc},
+    //    {"<", BackwardProc},
     //    {PAUSE_BUTTON, PauseProc},
-    {">", ForwardProc},
-    {">>", ToEndProc},
+    //    {">", ForwardProc},
+  //    {">>", ToEndProc},
     {NULL, NULL}
 };
 
@@ -725,15 +795,6 @@ DropMenuEnables dmEnables[] = {
     { 'Q', "Queen" }
 };
 
-Arg shellArgs[] = {
-    { XtNwidth, 0 },
-    { XtNheight, 0 },
-    { XtNminWidth, 0 },
-    { XtNminHeight, 0 },
-    { XtNmaxWidth, 0 },
-    { XtNmaxHeight, 0 }
-};
-
 Arg layoutArgs[] = {
     { XtNborderWidth, 0 },
     { XtNdefaultDistance, 0 },
@@ -750,25 +811,6 @@ Arg boardArgs[] = {
     { XtNheight, 0 }
 };
 
-Arg titleArgs[] = {
-    { XtNjustify, (XtArgVal) XtJustifyRight },
-    { XtNlabel, (XtArgVal) "..." },
-    { XtNresizable, (XtArgVal) True },
-    { XtNresize, (XtArgVal) False }
-};
-
-Arg messageArgs[] = {
-    { XtNjustify, (XtArgVal) XtJustifyLeft },
-    { XtNlabel, (XtArgVal) "..." },
-    { XtNresizable, (XtArgVal) True },
-    { XtNresize, (XtArgVal) False }
-};
-
-Arg timerArgs[] = {
-    { XtNborderWidth, 0 },
-    { XtNjustify, (XtArgVal) XtJustifyLeft }
-};
-
 XtResource clientResources[] = {
     { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
        XtOffset(AppDataPtr, whitePieceColor), XtRString,
@@ -1002,7 +1044,7 @@ XtResource clientResources[] = {
     { "localLineEditing", "localLineEditing", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, localLineEditing),
        XtRImmediate, (XtPointer) True }, /* not implemented, must be True */
-#ifdef ZIPPY
+#if ZIPPY
     { "zippyTalk", "zippyTalk", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
        XtRImmediate, (XtPointer) ZIPPY_TALK },
@@ -1209,6 +1251,9 @@ XtResource clientResources[] = {
     { "adjudicateLossThreshold", "adjudicateLossThreshold", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, adjudicateLossThreshold),
        XtRImmediate, (XtPointer) 0},
+    { "adjudicateDrawMoves", "adjudicateDrawMoves", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, adjudicateDrawMoves),
+       XtRImmediate, (XtPointer) 0},
     { "pgnEventHeader", "pgnEventHeader", XtRString,
         sizeof(String), XtOffset(AppDataPtr, pgnEventHeader),
        XtRImmediate, (XtPointer) "Computer Chess Game" },
@@ -1324,7 +1369,7 @@ XtResource clientResources[] = {
        XtRImmediate, (XtPointer) "xboard.debug"},
     { "engineDebugOutput", "engineDebugOutput", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, engineComments),
-       XtRImmediate, (XtPointer) 0},
+       XtRImmediate, (XtPointer) 1},
     { "noGUI", "noGUI", XtRBoolean,
        sizeof(Boolean), XtOffset(AppDataPtr, noGUI),
        XtRImmediate, (XtPointer) 0},
@@ -1378,6 +1423,12 @@ XtResource clientResources[] = {
     { "delayAfterQuit", "delayAfterQuit", XtRInt,
        sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),
        XtRImmediate, (XtPointer) 0},
+    { "keepAlive", "keepAlive", XtRInt,
+       sizeof(int), XtOffset(AppDataPtr, keepAlive),
+       XtRImmediate, (XtPointer) 0},
+    { "forceIllegalMoves", "forceIllegalMoves", XtRBoolean,
+       sizeof(Boolean), XtOffset(AppDataPtr, forceIllegal),
+       XtRImmediate, (XtPointer) False},
 };
 
 XrmOptionDescRec shellOptions[] = {
@@ -1677,6 +1728,7 @@ XrmOptionDescRec shellOptions[] = {
     { "-pgnExtendedInfo", "pgnExtendedInfo", XrmoptionSepArg, NULL },
     { "-hideThinkingFromHuman", "hideThinkingFromHuman", XrmoptionSepArg, NULL },
     { "-adjudicateLossThreshold", "adjudicateLossThreshold", XrmoptionSepArg, NULL },
+    { "-adjudicateDrawMoves", "adjudicateDrawMoves", XrmoptionSepArg, NULL },
     { "-pgnEventHeader", "pgnEventHeader", XrmoptionSepArg, NULL },
     { "-firstIsUCI", "firstIsUCI", XrmoptionSepArg, NULL },
     { "-secondIsUCI", "secondIsUCI", XrmoptionSepArg, NULL },
@@ -1744,6 +1796,8 @@ XrmOptionDescRec shellOptions[] = {
     { "-secondOptions", "secondOptions", XrmoptionSepArg, NULL },
     { "-firstNeedsNoncompliantFEN", "firstNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
     { "-secondNeedsNoncompliantFEN", "secondNeedsNoncompliantFEN", XrmoptionSepArg, NULL },
+    { "-keepAlive", "keepAlive", XrmoptionSepArg, NULL },
+    { "-forceIllegalMoves", "forceIllegalMoves", XrmoptionNoArg, "True" },
 };
 
 
@@ -1770,44 +1824,44 @@ XtActionsRec boardActions[] = {
     { "SavePositionProc", SavePositionProc },
     { "MailMoveProc", MailMoveProc },
     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
-    { "MachineWhiteProc", MachineWhiteProc },
-    { "MachineBlackProc", MachineBlackProc },
+    //    { "MachineWhiteProc", MachineWhiteProc },
+    //    { "MachineBlackProc", MachineBlackProc },
     { "AnalysisModeProc", AnalyzeModeProc },
     { "AnalyzeFileProc", AnalyzeFileProc },
-    { "TwoMachinesProc", TwoMachinesProc },
-    { "IcsClientProc", IcsClientProc },
+    //    { "TwoMachinesProc", TwoMachinesProc },
+    //    { "IcsClientProc", IcsClientProc },
     { "EditGameProc", EditGameProc },
     { "EditPositionProc", EditPositionProc },
     { "TrainingProc", EditPositionProc },
     { "EngineOutputProc", EngineOutputProc}, // [HGM] Winboard_x engine-output window
     { "ShowGameListProc", ShowGameListProc },
-    { "ShowMoveListProc", HistoryShowProc},
+    //    { "ShowMoveListProc", HistoryShowProc},
     { "EditTagsProc", EditCommentProc },
     { "EditCommentProc", EditCommentProc },
     { "IcsAlarmProc", IcsAlarmProc },
     { "IcsInputBoxProc", IcsInputBoxProc },
-    { "AcceptProc", AcceptProc },
-    { "DeclineProc", DeclineProc },
-    { "RematchProc", RematchProc },
-    { "CallFlagProc", CallFlagProc },
-    { "DrawProc", DrawProc },
-    { "AdjournProc", AdjournProc },
-    { "AbortProc", AbortProc },
-    { "ResignProc", ResignProc },
-    { "AdjuWhiteProc", AdjuWhiteProc },
-    { "AdjuBlackProc", AdjuBlackProc },
-    { "AdjuDrawProc", AdjuDrawProc },
+    //    { "AcceptProc", AcceptProc },
+    //    { "DeclineProc", DeclineProc },
+    //    { "RematchProc", RematchProc },
+    //    { "CallFlagProc", CallFlagProc },
+    //    { "DrawProc", DrawProc },
+    //    { "AdjournProc", AdjournProc },
+    //    { "AbortProc", AbortProc },
+    //    { "ResignProc", ResignProc },
+    //    { "AdjuWhiteProc", AdjuWhiteProc },
+    //    { "AdjuBlackProc", AdjuBlackProc },
+    //    { "AdjuDrawProc", AdjuDrawProc },
     { "EnterKeyProc", EnterKeyProc },
-    { "StopObservingProc", StopObservingProc },
-    { "StopExaminingProc", StopExaminingProc },
-    { "BackwardProc", BackwardProc },
-    { "ForwardProc", ForwardProc },
-    { "ToStartProc", ToStartProc },
-    { "ToEndProc", ToEndProc },
-    { "RevertProc", RevertProc },
-    { "TruncateGameProc", TruncateGameProc },
-    { "MoveNowProc", MoveNowProc },
-    { "RetractMoveProc", RetractMoveProc },
+    //    { "StopObservingProc", StopObservingProc },
+    //    { "StopExaminingProc", StopExaminingProc },
+    //    { "BackwardProc", BackwardProc },
+    //    { "ForwardProc", ForwardProc },
+    //    { "ToStartProc", ToStartProc },
+    //    { "ToEndProc", ToEndProc },
+    //    { "RevertProc", RevertProc },
+    //    { "TruncateGameProc", TruncateGameProc },
+    //    { "MoveNowProc", MoveNowProc },
+    //    { "RetractMoveProc", RetractMoveProc },
     { "AlwaysQueenProc", AlwaysQueenProc },
     { "AnimateDraggingProc", AnimateDraggingProc },
     { "AnimateMovingProc", AnimateMovingProc },
@@ -1818,8 +1872,8 @@ XtActionsRec boardActions[] = {
     { "AutosaveProc", AutosaveProc },
     { "BlindfoldProc", BlindfoldProc },
     { "FlashMovesProc", FlashMovesProc },
-    { "FlipViewProc", FlipViewProc },
-    { "GetMoveListProc", GetMoveListProc },
+    //    { "FlipViewProc", FlipViewProc },
+    //    { "GetMoveListProc", GetMoveListProc },
 #if HIGHDRAG
     { "HighlightDraggingProc", HighlightDraggingProc },
 #endif
@@ -1833,13 +1887,13 @@ XtActionsRec boardActions[] = {
     { "PopupMoveErrorsProc", PopupMoveErrorsProc },
     { "PremoveProc", PremoveProc },
     { "QuietPlayProc", QuietPlayProc },
-    { "ShowThinkingProc", ShowThinkingProc },
-    { "HideThinkingProc", HideThinkingProc },
+    //    { "ShowThinkingProc", ShowThinkingProc },
+    //    { "HideThinkingProc", HideThinkingProc },
     { "TestLegalityProc", TestLegalityProc },
-    { "InfoProc", InfoProc },
-    { "ManProc", ManProc },
-    { "HintProc", HintProc },
-    { "BookProc", BookProc },
+    //    { "InfoProc", InfoProc },
+    //    { "ManProc", ManProc },
+    //    { "HintProc", HintProc },
+    //    { "BookProc", BookProc },
     { "AboutGameProc", AboutGameProc },
     { "DebugProc", DebugProc },
     { "NothingProc", NothingProc },
@@ -1853,7 +1907,7 @@ XtActionsRec boardActions[] = {
     { "AskQuestionPopDown", (XtActionProc) AskQuestionPopDown },
     { "GameListPopDown", (XtActionProc) GameListPopDown },
     { "PromotionPopDown", (XtActionProc) PromotionPopDown },
-    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
+    //    { "HistoryPopDown", (XtActionProc) HistoryPopDown },
     { "EngineOutputPopDown", (XtActionProc) EngineOutputPopDown },
     { "ShufflePopDown", (XtActionProc) ShufflePopDown },
     { "EnginePopDown", (XtActionProc) EnginePopDown },
@@ -2036,7 +2090,7 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
        }
 #ifdef GOTHIC
        if(gameInfo.variant == VariantGothic) {
-           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[i][(int)WhiteSilver];
+           ximMaskPm[(int)WhiteMarshall] = ximMaskPm2[(int)WhiteSilver];
        }
 #endif
 #endif
@@ -2066,6 +2120,19 @@ void InitDrawingSizes(BoardSize boardSize, int flags)
 }
 #endif
 
+void EscapeExpand(char *p, char *q)
+{      // [HGM] initstring: routine to shape up string arguments
+       while(*p++ = *q++) if(p[-1] == '\\')
+           switch(*q++) {
+               case 'n': p[-1] = '\n'; break;
+               case 'r': p[-1] = '\r'; break;
+               case 't': p[-1] = '\t'; break;
+               case '\\': p[-1] = '\\'; break;
+               case 0: *p = 0; return;
+               default: p[-1] = q[-1]; break;
+           }
+}
+
 int
 main(argc, argv)
      int argc;
@@ -2118,14 +2185,8 @@ main(argc, argv)
     argvCopy[j] = NULL;
     argv = argvCopy;
     argc = j;
-#if 0
-    if(appData.debugMode,1) { // OK, appData is not initialized here yet...
-       for(i=0; i<argc; i++) fprintf(stderr, "argv[%2d] = '%s'\n", i, argv[i]);
-    }
-#endif
 #endif
 
-
     setbuf(stdout, NULL);
     setbuf(stderr, NULL);
     debugFP = stderr;
@@ -2147,7 +2208,6 @@ main(argc, argv)
                      XtNumber(shellOptions),
                      &argc, argv, xboardResources, NULL, 0);
 
-
     /* set up GTK */
     gtk_init (&argc, &argv);
 
@@ -2160,13 +2220,23 @@ main(argc, argv)
 
     GUI_Window = GTK_WIDGET (gtk_builder_get_object (builder, "MainWindow"));
     if(!GUI_Window) printf("Error: gtk_builder didn't work!\n");
+
+    GUI_History = GTK_WIDGET (gtk_builder_get_object (builder, "MoveHistory"));
+    if(!GUI_History) printf("Error: gtk_builder didn't work!\n");
+
     GUI_Board  = GTK_WIDGET (gtk_builder_get_object (builder, "Board"));
     if(!GUI_Board) printf("Error: gtk_builder didn't work!\n");
+
     GUI_Whiteclock  = GTK_WIDGET (gtk_builder_get_object (builder, "WhiteClock"));
     if(!GUI_Whiteclock) printf("Error: gtk_builder didn't work!\n");
+
     GUI_Blackclock  = GTK_WIDGET (gtk_builder_get_object (builder, "BlackClock"));
     if(!GUI_Blackclock) printf("Error: gtk_builder didn't work!\n");
 
+    LIST_MoveHistory = GTK_LIST_STORE (gtk_builder_get_object (builder, "MoveHistoryStore"));
+    if(!LIST_MoveHistory) printf("Error: gtk_builder didn't work!\n");
+
+
     gtk_builder_connect_signals (builder, NULL);
 
     // don't unref the builder, since we use it to get references to widgets
@@ -2178,40 +2248,29 @@ main(argc, argv)
       {
        fprintf(stderr, _("%s: unrecognized argument %s\n"),
                programName, argv[1]);
+
        fprintf(stderr, "Recognized options:\n");
-       for(i = 0; i < XtNumber(shellOptions); i++)
+       for(i = 0; i < XtNumber(shellOptions); i++) 
          {
+           /* print first column */
            j = fprintf(stderr, "  %s%s", shellOptions[i].option,
                        (shellOptions[i].argKind == XrmoptionSepArg
                         ? " ARG" : ""));
-           if (i++ < XtNumber(shellOptions))
-             {
+           /* print second column and end line */
+           if (++i < XtNumber(shellOptions)) 
+             {         
                fprintf(stderr, "%*c%s%s\n", 40 - j, ' ',
                        shellOptions[i].option,
                        (shellOptions[i].argKind == XrmoptionSepArg
                         ? " ARG" : ""));
-             }
-           else
+             } 
+           else 
              {
                fprintf(stderr, "\n");
-             }
-         }
+             };
+         };
        exit(2);
-      }
-
-    if ((chessDir = (char *) getenv("CHESSDIR")) == NULL)
-      {
-       chessDir = ".";
-      }
-    else
-      {
-       if (chdir(chessDir) != 0)
-         {
-           fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
-           perror(chessDir);
-           exit(1);
-         }
-      }
+      };
 
     p = getenv("HOME");
     if (p == NULL) p = "/tmp";
@@ -2225,6 +2284,28 @@ main(argc, argv)
                              clientResources, XtNumber(clientResources),
                              NULL, 0);
 
+    { // [HGM] initstring: kludge to fix bad bug. expand '\n' characters in init string and computer string.
+       static char buf[MSG_SIZ];
+       EscapeExpand(buf, appData.initString);
+       appData.initString = strdup(buf);
+       EscapeExpand(buf, appData.secondInitString);
+       appData.secondInitString = strdup(buf);
+       EscapeExpand(buf, appData.firstComputerString);
+       appData.firstComputerString = strdup(buf);
+       EscapeExpand(buf, appData.secondComputerString);
+       appData.secondComputerString = strdup(buf);
+    }
+
+    if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
+       chessDir = ".";
+    } else {
+       if (chdir(chessDir) != 0) {
+           fprintf(stderr, _("%s: can't cd to CHESSDIR: "), programName);
+           perror(chessDir);
+           exit(1);
+       }
+    }
+
     if (appData.debugMode && appData.nameOfDebugFile && strcmp(appData.nameOfDebugFile, "stderr")) {
        /* [DM] debug info to file [HGM] make the filename a command-line option, and allow it to remain stderr */
         if ((debugFP = fopen(appData.nameOfDebugFile, "w")) == NULL)  {
@@ -2251,19 +2332,6 @@ main(argc, argv)
 
     gameInfo.variant = StringToVariant(appData.variant);
     InitPosition(FALSE);
-#if 0
-
-    /*
-     * Determine boardSize
-     */
-    gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] boardsize: make sure we start as 8x8
-
-    //#ifndef IDSIZE
-    // [HGM] as long as we have not created the possibility to change size while running, start with requested size
-    gameInfo.boardWidth    = appData.NrFiles > 0 ? appData.NrFiles : 8;
-    gameInfo.boardHeight   = appData.NrRanks > 0 ? appData.NrRanks : 8;
-    gameInfo.holdingsWidth = appData.holdingsSize > 0 ? 2 : 0;
-#endif
 
 
 #ifdef IDSIZE
@@ -2541,10 +2609,10 @@ main(argc, argv)
 
     if (appData.alwaysPromoteToQueen)
       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Always Queen")),TRUE);
-    
+
     if (appData.animateDragging)
       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Dragging")),TRUE);
-    
+
     if (appData.animate)
       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Animate Moving")),TRUE);
 
@@ -2627,7 +2695,7 @@ main(argc, argv)
       gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (gtk_builder_get_object (builder, "menuOptions.Test Legality")),TRUE);
 
     /* end setting check boxes */
-    
+
 
     /* load square colors */
     SVGLightSquare   = load_pixbuf("svg/LightSquare.svg",squareSize);
@@ -2641,7 +2709,7 @@ main(argc, argv)
     gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
 
     /* do resizing to a fixed aspect ratio */
-    
+
     {
       int i,j;
     }
@@ -2768,11 +2836,6 @@ ResetFrontEnd()
     return;
 }
 
-typedef struct {
-    char *name;
-    gboolean value;
-} Enables;
-
 void
 SetMenuEnables(enab)
      Enables *enab;
@@ -2795,162 +2858,13 @@ SetMenuEnables(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 },
-#ifndef ZIPPY
-    { "menuHelp.Hint", False },
-    { "menuHelp.Book", False },
-    { "menuStep.Move Now", False },
-    { "menuOptions.Periodic Updates", False },
-    { "menuOptions.Hide Thinking", False },
-    { "menuOptions.Ponder Next Move", False },
-#endif
-    { 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.ICS Client", False },
-    { "menuMode.ICS Input Box", False },
-    { "Action", False },
-    { "menuStep.Revert", False },
-    { "menuStep.Move Now", False },
-    { "menuStep.Retract Move", False },
-    { "menuOptions.Auto Comment", False },
-    { "menuOptions.Auto Flag", False },
-    { "menuOptions.Auto Flip View", False },
-    { "menuOptions.Auto Observe", False },
-    { "menuOptions.Auto Raise Board", False },
-    { "menuOptions.Get Move List", False },
-    { "menuOptions.ICS Alarm", False },
-    { "menuOptions.Move Sound", False },
-    { "menuOptions.Quiet Play", False },
-    { "menuOptions.Hide Thinking", False },
-    { "menuOptions.Periodic Updates", False },
-    { "menuOptions.Ponder Next Move", False },
-    { "menuHelp.Hint", False },
-    { "menuHelp.Book", False },
-    { NULL, False }
-};
-
-Enables gnuEnables[] = {
-    { "menuMode.ICS Client", False },
-    { "menuMode.ICS Input Box", False },
-    { "menuAction.Accept", False },
-    { "menuAction.Decline", False },
-    { "menuAction.Rematch", False },
-    { "menuAction.Adjourn", False },
-    { "menuAction.Stop Examining", False },
-    { "menuAction.Stop Observing", False },
-    { "menuStep.Revert", False },
-    { "menuOptions.Auto Comment", False },
-    { "menuOptions.Auto Observe", False },
-    { "menuOptions.Auto Raise Board", False },
-    { "menuOptions.Get Move List", False },
-    { "menuOptions.Premove", False },
-    { "menuOptions.Quiet Play", False },
-
-    /* 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 },
-    { 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 },
-  { "menuStep.Forward", False },
-  { "menuStep.Backward", False },
-  { "menuStep.Forward to End", False },
-  { "menuStep.Back to Start", False },
-  { "menuStep.Move Now", False },
-  { "menuStep.Truncate Game", False },
-  { NULL, False }
-};
-
-Enables trainingOffEnables[] = {
-  { "menuMode.Edit Comment", True },
-  { "menuMode.Pause", True },
-  { "menuStep.Forward", True },
-  { "menuStep.Backward", True },
-  { "menuStep.Forward to End", True },
-  { "menuStep.Back to Start", True },
-  { "menuStep.Move Now", True },
-  { "menuStep.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 },
-  { "menuFile.Paste Game", False },
-  { "menuFile.Load Position", False },
-  { "menuFile.Load Next Position", False },
-  { "menuFile.Load Previous Position", False },
-  { "menuFile.Reload Same Position", False },
-  { "menuFile.Paste Position", False },
-  { "menuMode.Machine White", False },
-  { "menuMode.Machine Black", False },
-  { "menuMode.Two Machines", False },
-  { "menuStep.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 },
-  { "menuFile.Paste Game", True },
-  { "menuFile.Load Position", True },
-  { "menuFile.Load Next Position", True },
-  { "menuFile.Load Previous Position", True },
-  { "menuFile.Reload Same Position", True },
-  { "menuFile.Paste Position", True },
-  { "menuMode.Machine White", True },
-  { "menuMode.Machine Black", True },
-  { "menuMode.Two Machines", True },
-  { "menuStep.Retract Move", True },
-  { NULL, False }
-};
-
 void SetICSMode()
 {
   SetMenuEnables(icsEnables);
 
 #ifdef ZIPPY
   if (appData.zippyPlay && !appData.noChessProgram)   /* [DM] icsEngineAnalyze */
-     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
+    {}; //     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuMode.Analysis Mode"), True);
 #endif
 }
 
@@ -2977,7 +2891,7 @@ SetTrainingModeOn()
 {
   SetMenuEnables(trainingOnEnables);
   if (appData.showButtonBar) {
-    XtSetSensitive(buttonBarWidget, False);
+    //    XtSetSensitive(buttonBarWidget, False);
   }
   CommentPopDown();
 }
@@ -2987,7 +2901,7 @@ SetTrainingModeOff()
 {
   SetMenuEnables(trainingOffEnables);
   if (appData.showButtonBar) {
-    XtSetSensitive(buttonBarWidget, True);
+    //    XtSetSensitive(buttonBarWidget, True);
   }
 }
 
@@ -3007,8 +2921,8 @@ SetMachineThinkingEnables()
   case MachinePlaysBlack:
   case MachinePlaysWhite:
   case TwoMachinesPlay:
-    XtSetSensitive(XtNameToWidget(menuBarWidget,
-                                 ModeToWidgetName(gameMode)), True);
+//    XtSetSensitive(XtNameToWidget(menuBarWidget,
+//                               ModeToWidgetName(gameMode)), True);
     break;
   default:
     break;
@@ -3203,6 +3117,12 @@ void CreatePieces()
   WhitePawn, WhiteKnight, WhiteBishop, WhiteRook, WhiteQueen, WhiteKing,
   BlackPawn, BlackKnight, BlackBishop, BlackRook, BlackQueen, BlackKing,
   */
+  int i;
+
+  /* get some defaults going */
+  for(i=WhitePawn; i<DemotePiece+1; i++)
+    SVGpieces[i]   = load_pixbuf("svg/NeutralSquare.svg",squareSize);
+    
 
   SVGpieces[WhitePawn]   = load_pixbuf("svg/WhitePawn.svg",squareSize);
   SVGpieces[WhiteKnight] = load_pixbuf("svg/WhiteKnight.svg",squareSize);
@@ -3691,19 +3611,22 @@ static void BlankSquare(x, y, color, piece, dest)
      Drawable dest;
 {
       GdkPixbuf *pb;
-      switch (color) {
-      case 1: /* light */
-       pb = SVGLightSquare;
-       break;
-      case 0: /* dark */
-       pb = SVGDarkSquare;
-       break;
-      case 2: /* neutral */
-      default:
-       pb = SVGNeutralSquare;
-       break;
-      }
+
+      switch (color) 
+       {
+       case 0: /* dark */
+         pb = SVGDarkSquare;
+         break;
+       case 1: /* light */
+         pb = SVGLightSquare;
+         break;
+       case 2: /* neutral */
+       default:
+         pb = SVGNeutralSquare;
+         break;
+       }
       gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,pb,0,0,x,y,-1,-1, GDK_RGB_DITHER_NORMAL, 0, 0);
+      return;
 }
 
 static void DrawPiece(piece, square_color, x, y, dest)
@@ -3711,6 +3634,10 @@ static void DrawPiece(piece, square_color, x, y, dest)
      int square_color, x, y;
      Drawable dest;
 {
+  /* redraw background, since piece might be transparent in some areas */
+  BlankSquare(x,y,square_color,piece,dest);
+
+  /* draw piece */
   gdk_draw_pixbuf(GDK_WINDOW(GUI_Board->window),NULL,
                  GDK_PIXBUF(SVGpieces[piece]),0,0,x,y,-1,-1,
                  GDK_RGB_DITHER_NORMAL, 0, 0);
@@ -3777,7 +3704,7 @@ void DrawSquare(row, column, piece, do_flash)
         || (column == BOARD_RGHT+1 && row >= gameInfo.holdingsSize) )
       {
        BlankSquare(x, y, 2, EmptySquare, xBoardWindow);
-       
+
        // [HGM] print piece counts next to holdings
        string[1] = NULLCHAR;
        if(piece > 1)
@@ -3788,17 +3715,16 @@ void DrawSquare(row, column, piece, do_flash)
 
            /* get a cairo_t */
            cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
-           
+
            string[0] = '0' + piece;
-           
+
            /* TODO this has to go into the font-selection */
            cairo_select_font_face (cr, "Sans",
                                    CAIRO_FONT_SLANT_NORMAL,
                                    CAIRO_FONT_WEIGHT_NORMAL);
-           
+
            cairo_set_font_size (cr, 12.0);
            cairo_text_extents (cr, string, &extents);
-           
 
            if (column == (flipView ? BOARD_LEFT-1 : BOARD_RGHT) )
              {
@@ -3819,11 +3745,10 @@ void DrawSquare(row, column, piece, do_flash)
            cairo_set_source_rgb (cr, 0, 0, 0);
            cairo_set_line_width (cr, 0.1);
            cairo_stroke (cr);
-                   
+
            /* free memory */
            cairo_destroy (cr);
          }
-
       }
     else
       {
@@ -3862,13 +3787,13 @@ void DrawSquare(row, column, piece, do_flash)
                                CAIRO_FONT_SLANT_NORMAL,
                                CAIRO_FONT_WEIGHT_NORMAL);
        cairo_set_font_size (cr, 12.0);
-               
+
        string[1] = NULLCHAR;
 
        /* get a cairo_t */
        cr = gdk_cairo_create (GDK_WINDOW(GUI_Board->window));
-       
-       if (row == (flipView ? BOARD_HEIGHT-1 : 0) && 
+
+       if (row == (flipView ? BOARD_HEIGHT-1 : 0) &&
            column >= BOARD_LEFT && column < BOARD_RGHT)
          {
            string[0] = 'a' + column - BOARD_LEFT;
@@ -4159,16 +4084,46 @@ void HandleUserMove(w, event, prms, nprms)
 {
     int x, y;
     Boolean saveAnimate;
-    static int second = 0;
+    static int second = 0, promotionChoice = 0;
+    ChessMove moveType;
 
     if (w != boardWidget || errorExitStatus != -1) return;
 
+    x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
+    y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
+    if (!flipView && y >= 0) {
+       y = BOARD_HEIGHT - 1 - y;
+    }
+    if (flipView && x >= 0) {
+       x = BOARD_WIDTH - 1 - x;
+    }
+
+    if(promotionChoice) { // we are waiting for a click to indicate promotion piece
+       if(event->type == ButtonRelease) return; // ignore upclick of click-click destination
+       promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel
+       if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);
+       if(gameInfo.holdingsWidth && 
+               (WhiteOnMove(currentMove) 
+                       ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0
+                       : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {
+           // click in right holdings, for determining promotion piece
+           ChessSquare p = boards[currentMove][y][x];
+           if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);
+           if(p != EmptySquare) {
+               FinishMove(NormalMove, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));
+               fromX = fromY = -1;
+               return;
+           }
+       }
+       DrawPosition(FALSE, boards[currentMove]);
+       return;
+    }
     if (event->type == ButtonPress) ErrorPopDown();
 
     if (promotionUp) {
        if (event->type == ButtonPress) {
-           XtPopdown(promotionShell);
-           XtDestroyWidget(promotionShell);
+//         XtPopdown(promotionShell);
+//         XtDestroyWidget(promotionShell);
            promotionUp = False;
            ClearHighlights();
            fromX = fromY = -1;
@@ -4177,25 +4132,17 @@ void HandleUserMove(w, event, prms, nprms)
        }
     }
 
-    x = EventToSquare(event->xbutton.x, BOARD_WIDTH);
-    y = EventToSquare(event->xbutton.y, BOARD_HEIGHT);
-    if (!flipView && y >= 0) {
-       y = BOARD_HEIGHT - 1 - y;
-    }
-    if (flipView && x >= 0) {
-       x = BOARD_WIDTH - 1 - x;
-    }
-
     /* [HGM] holdings: next 5 lines: ignore all clicks between board and holdings */
     if(event->type == ButtonPress
-            && ( x == BOARD_LEFT-1 || x == BOARD_RGHT
-              || x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize
-              || x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize) )
+            && ( x == BOARD_LEFT-1 || 
+                x == BOARD_RGHT   || 
+                (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize ) || 
+                (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize)) )
        return;
 
     if (fromX == -1) {
        if (event->type == ButtonPress) {
-           /* First square */
+           /* First square, prepare to drag */
            if (OKToStartUserMove(x, y)) {
                fromX = x;
                fromY = y;
@@ -4210,35 +4157,8 @@ void HandleUserMove(w, event, prms, nprms)
     }
 
     /* fromX != -1 */
-    if (event->type == ButtonPress && gameMode != EditPosition &&
-       x >= 0 && y >= 0) {
-       ChessSquare fromP;
-       ChessSquare toP;
-
-       /* Check if clicking again on the same color piece */
-       fromP = boards[currentMove][fromY][fromX];
-       toP = boards[currentMove][y][x];
-       if ((WhitePawn <= fromP && fromP < WhiteKing && // [HGM] this test should go, as UserMoveTest now does it.
-            WhitePawn <= toP && toP <= WhiteKing) ||   //       For now I made it less critical by exempting King
-           (BlackPawn <= fromP && fromP < BlackKing && //       moves, to not interfere with FRC castlings.
-            BlackPawn <= toP && toP <= BlackKing)) {
-           /* Clicked again on same color piece -- changed his mind */
-           second = (x == fromX && y == fromY);
-           if (appData.highlightDragging) {
-               SetHighlights(x, y, -1, -1);
-           } else {
-               ClearHighlights();
-           }
-           if (OKToStartUserMove(x, y)) {
-               fromX = x;
-               fromY = y;
-               DragPieceBegin(event->xbutton.x, event->xbutton.y);
-           }
-           return;
-       }
-    }
-
     if (event->type == ButtonRelease &&        x == fromX && y == fromY) {
+    /* Click on single square in stead of drag-drop */
        DragPieceEnd(event->xbutton.x, event->xbutton.y);
        if (appData.animateDragging) {
            /* Undo animation damage if any */
@@ -4258,7 +4178,34 @@ void HandleUserMove(w, event, prms, nprms)
        return;
     }
 
-    /* Completed move */
+    moveType = UserMoveTest(fromX, fromY, x, y, NULLCHAR, event->type == ButtonRelease);
+
+    if (moveType == Comment) { // kludge for indicating capture-own on Press
+      /* Clicked again on same color piece -- changed his mind */
+      /* note that re-clicking same square always hits same color piece */
+      second = (x == fromX && y == fromY);
+      if (appData.highlightDragging) {
+       SetHighlights(x, y, -1, -1);
+      } else {
+       ClearHighlights();
+      }
+      if (OKToStartUserMove(x, y)) {
+       fromX = x;
+       fromY = y;
+       DragPieceBegin(event->xbutton.x, event->xbutton.y);
+      }
+      return;
+    }
+
+    if(moveType == AmbiguousMove) { // kludge to indicate edit-position move
+      fromX = fromY = -1; 
+      ClearHighlights();
+      DragPieceEnd(event->xbutton.x, event->xbutton.y);
+      DrawPosition(FALSE, boards[currentMove]);
+      return;
+    }
+
+    /* Complete move; (x,y) is now different from (fromX, fromY) on both Press and Release */
     toX = x;
     toY = y;
     saveAnimate = appData.animate;
@@ -4280,22 +4227,38 @@ void HandleUserMove(w, event, prms, nprms)
        /* Don't animate move and drag both */
        appData.animate = FALSE;
     }
-    if (IsPromotion(fromX, fromY, toX, toY)) {
-       if (appData.alwaysPromoteToQueen) {
-           UserMoveEvent(fromX, fromY, toX, toY, 'q');
+    if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||
+        (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&
+            appData.alwaysPromoteToQueen) { // promotion, but no choice
+      FinishMove(moveType, fromX, fromY, toX, toY, 'q');
+    } else
+    if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {
+       SetHighlights(fromX, fromY, toX, toY);
+       if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) {
+           // [HGM] super: promotion to captured piece selected from holdings
+           ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];
+           promotionChoice = TRUE;
+           // kludge follows to temporarily execute move on display, without promoting yet
+           boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank
+           boards[currentMove][toY][toX] = p;
+           DrawPosition(FALSE, boards[currentMove]);
+           boards[currentMove][fromY][fromX] = p; // take back, but display stays
+           boards[currentMove][toY][toX] = q;
+           DisplayMessage("Click in holdings to choose piece", "");
+           return;
+       }
+       PromotionPopUp();
+       goto skipClearingFrom; // the skipped stuff is done asynchronously by PromotionCallback
+    } else
+    if(moveType != ImpossibleMove) { // valid move, but no promotion
+      FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);
+    } else { // invalid move; could have set premove
+      ClearHighlights();
+    }
            if (!appData.highlightLastMove || gotPremove) ClearHighlights();
            if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
            fromX = fromY = -1;
-       } else {
-           SetHighlights(fromX, fromY, toX, toY);
-           PromotionPopUp();
-       }
-    } else {
-       UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
-       if (!appData.highlightLastMove || gotPremove) ClearHighlights();
-       if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
-       fromX = fromY = -1;
-    }
+skipClearingFrom:
     appData.animate = saveAnimate;
     if (appData.animate || appData.animateDragging) {
        /* Undo animation damage if needed */
@@ -4354,12 +4317,8 @@ Widget CommentCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
     XtSetArg(args[j], XtNwidth, bw_width);  j++; /*force wider than buttons*/
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -4512,12 +4471,8 @@ Widget MiscCreate(name, text, mutable, callback, lines)
     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
     XtSetArg(args[j], XtNright, XtChainRight);  j++;
     XtSetArg(args[j], XtNresizable, True);  j++;
-#if 0
-    XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
-#else
     /* !!Work around an apparent bug in XFree86 4.0.1 (X11R6.4.3) */
     XtSetArg(args[j], XtNscrollVertical, XawtextScrollAlways);  j++;
-#endif
     XtSetArg(args[j], XtNautoFill, True);  j++;
     XtSetArg(args[j], XtNwrap, XawtextWrapWord); j++;
     edit =
@@ -5080,7 +5035,7 @@ void PromotionCallback(w, client_data, call_data)
        promoChar = ToLower(name[0]);
     }
 
-    UserMoveEvent(fromX, fromY, toX, toY, promoChar);
+    FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar);
 
     if (!appData.highlightLastMove || gotPremove) ClearHighlights();
     if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);
@@ -5103,37 +5058,41 @@ void ErrorPopDown()
 {
     if (!errorUp) return;
     errorUp = False;
-    XtPopdown(errorShell);
-    XtDestroyWidget(errorShell);
+
+    if(GUI_Error)
+      gtk_widget_destroy(GTK_WIDGET(GUI_Error));
+
     if (errorExitStatus != -1) ExitEvent(errorExitStatus);
+
+    return;
 }
 
 void ErrorPopUp(title, label, modal)
      char *title, *label;
      int modal;
 {
-  GtkWidget *dialog;
-
-  dialog = gtk_message_dialog_new(GTK_WINDOW(GUI_Window),
+  GUI_Error = gtk_message_dialog_new(GTK_WINDOW(GUI_Window),
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_ERROR,
                                   GTK_BUTTONS_CLOSE,
                                   (gchar *)label);
 
-  gtk_window_set_title(GTK_WINDOW(dialog),(gchar *) title);
+  gtk_window_set_title(GTK_WINDOW(GUI_Error),(gchar *) title);
   if(modal)
     {
-      gtk_dialog_run(GTK_DIALOG(dialog));
-      gtk_widget_destroy(GTK_WIDGET(dialog));
+      gtk_dialog_run(GTK_DIALOG(GUI_Error));
+      gtk_widget_destroy(GTK_WIDGET(GUI_Error));
     }
   else
     {
-      g_signal_connect_swapped (dialog, "response",
+      g_signal_connect_swapped (GUI_Error, "response",
                                 G_CALLBACK (ErrorPopDownProc),
-                                dialog);
+                                GUI_Error);
       errorUp = True;
-      gtk_widget_show(GTK_WIDGET(dialog));
+      gtk_widget_show(GTK_WIDGET(GUI_Error));
     }
+
+  return;
 }
 
 /* Disable all user input other than deleting the window */
@@ -5242,18 +5201,26 @@ int LoadGamePopUp(f, gameNumber, title)
      char *title;
 {
     cmailMsgLoaded = FALSE;
-    if (gameNumber == 0) {
+
+    if (gameNumber == 0) 
+      {
        int error = GameListBuild(f);
-       if (error) {
+
+       if (error) 
+         {
            DisplayError(_("Cannot build game list"), error);
-       } else if (!ListEmpty(&gameList) &&
-                  ((ListGame *) gameList.tailPred)->number > 1) {
+         } 
+       else if (!ListEmpty(&gameList) 
+                && ((ListGame *) gameList.tailPred)->number > 1) 
+         {
            GameListPopUp(f, title);
            return TRUE;
-       }
+         };
+
        GameListDestroy();
        gameNumber = 1;
-    }
+      };
+
     return LoadGame(f, gameNumber, title, FALSE);
 }
 
@@ -5521,24 +5488,6 @@ void AutoSaveGame()
     SaveGameProc(NULL, NULL, NULL, NULL);
 }
 
-void MachineBlackProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    MachineBlackEvent();
-}
-
-void MachineWhiteProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    MachineWhiteEvent();
-}
-
 void AnalyzeModeProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -5577,7 +5526,7 @@ void AnalyzeModeProc(w, event, prms, nprms)
             fprintf(debugFP, _("ICS engine analyze starting... \n"));
     }
     if (!appData.showThinking)
-      ShowThinkingProc(w,event,prms,nprms);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeModeEvent();
 }
@@ -5597,30 +5546,13 @@ void AnalyzeFileProc(w, event, prms, nprms)
     Reset(FALSE, TRUE);
 
     if (!appData.showThinking)
-      ShowThinkingProc(w,event,prms,nprms);
+      ShowThinkingProc(NULL,NULL);
 
     AnalyzeFileEvent();
     FileNamePopUp(_("File to analyze"), "", LoadGamePopUp, "rb");
     AnalysisPeriodicEvent(1);
 }
 
-void TwoMachinesProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    TwoMachinesEvent();
-}
-
-void IcsClientProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    IcsClientEvent();
-}
 
 void EditGameProc(w, event, prms, nprms)
      Widget w;
@@ -5675,104 +5607,6 @@ void IcsInputBoxProc(w, event, prms, nprms)
     }
 }
 
-void AcceptProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    AcceptEvent();
-}
-
-void DeclineProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    DeclineEvent();
-}
-
-void RematchProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    RematchEvent();
-}
-
-void CallFlagProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    CallFlagEvent();
-}
-
-void DrawProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    DrawEvent();
-}
-
-void AbortProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    AbortEvent();
-}
-
-void AdjournProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    AdjournEvent();
-}
-
-void ResignProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ResignEvent();
-}
-
-void AdjuWhiteProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    UserAdjudicationEvent(+1);
-}
-
-void AdjuBlackProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    UserAdjudicationEvent(-1);
-}
-
-void AdjuDrawProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    UserAdjudicationEvent(0);
-}
 
 void EnterKeyProc(w, event, prms, nprms)
      Widget w;
@@ -5784,98 +5618,6 @@ void EnterKeyProc(w, event, prms, nprms)
       ICSInputSendText();
 }
 
-void StopObservingProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    StopObservingEvent();
-}
-
-void StopExaminingProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    StopExaminingEvent();
-}
-
-
-void ForwardProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ForwardEvent();
-}
-
-
-void BackwardProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    BackwardEvent();
-}
-
-void ToStartProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ToStartEvent();
-}
-
-void ToEndProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    ToEndEvent();
-}
-
-void RevertProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    RevertEvent();
-}
-
-void TruncateGameProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    TruncateGameEvent();
-}
-void RetractMoveProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    RetractMoveEvent();
-}
-
-void MoveNowProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    MoveNowEvent();
-}
-
-
 void AlwaysQueenProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6114,36 +5856,6 @@ void FlashMovesProc(w, event, prms, nprms)
                args, 1);
 }
 
-void FlipViewProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    flipView = !flipView;
-    DrawPosition(True, NULL);
-}
-
-void GetMoveListProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.getMoveList = !appData.getMoveList;
-
-    if (appData.getMoveList) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-       GetMoveListEvent();
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Get Move List"),
-               args, 1);
-}
-
 #if HIGHDRAG
 void HighlightDraggingProc(w, event, prms, nprms)
      Widget w;
@@ -6356,94 +6068,6 @@ void QuietPlayProc(w, event, prms, nprms)
                args, 1);
 }
 
-void ShowThinkingProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    Arg args[16];
-
-    appData.showThinking = !appData.showThinking; // [HGM] thinking: tken out of ShowThinkingEvent
-    ShowThinkingEvent();
-#if 0
-    // [HGM] thinking: currently no suc menu item; replaced by Hide Thinking (From Human)
-    if (appData.showThinking) {
-       XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
-    } else {
-       XtSetArg(args[0], XtNleftBitmap, None);
-    }
-    XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
-               args, 1);
-#endif
-}
-
-void HideThinkingProc(w, event, prms, nprms)
-     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);
-}
-
-void InfoProc(w, event, prms, nprms)
-     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(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    char buf[MSG_SIZ];
-    String name;
-    if (nprms && *nprms > 0)
-      name = prms[0];
-    else
-      name = "xboard";
-    snprintf(buf, sizeof(buf), "xterm -e man %s &", name);
-    system(buf);
-}
-
-void HintProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    HintEvent();
-}
-
-void BookProc(w, event, prms, nprms)
-     Widget w;
-     XEvent *event;
-     String *prms;
-     Cardinal *nprms;
-{
-    BookEvent();
-}
-
 void DebugProc(w, event, prms, nprms)
      Widget w;
      XEvent *event;
@@ -6499,55 +6123,58 @@ void DisplayMessage(message, extMessage)
        }
     }
     gtk_label_set_text( GTK_LABEL(gtk_builder_get_object (builder, "Messages")),message);
+
+    return;
 }
 
 void DisplayTitle(text)
      char *text;
 {
-    Arg args[16];
-    int i;
-    char title[MSG_SIZ];
-    char icon[MSG_SIZ];
+    gchar title[MSG_SIZ];
 
     if (text == NULL) text = "";
 
-    if (appData.titleInWindow) {
-       i = 0;
-       XtSetArg(args[i], XtNlabel, text);   i++;
-       XtSetValues(titleWidget, args, i);
-    }
+    if (appData.titleInWindow)
+      {
+       /* TODO */
+      }
 
-    if (*text != NULLCHAR) {
-       strcpy(icon, text);
+    if (*text != NULLCHAR)
+      {
        strcpy(title, text);
-    } else if (appData.icsActive) {
-        snprintf(icon, sizeof(icon), "%s", appData.icsHost);
+      }
+    else if (appData.icsActive)
+      {
        snprintf(title, sizeof(title), "%s: %s", programName, appData.icsHost);
-    } else if (appData.cmailGameName[0] != NULLCHAR) {
-        snprintf(icon, sizeof(icon), "%s", "CMail");
+      }
+    else if (appData.cmailGameName[0] != NULLCHAR)
+      {
        snprintf(title,sizeof(title), "%s: %s", programName, "CMail");
 #ifdef GOTHIC
     // [HGM] license: This stuff should really be done in back-end, but WinBoard already had a pop-up for it
-    } else if (gameInfo.variant == VariantGothic) {
-       strcpy(icon, programName);
+      }
+    else if (gameInfo.variant == VariantGothic)
+      {
        strcpy(title, GOTHIC);
 #endif
 #ifdef FALCON
-    } else if (gameInfo.variant == VariantFalcon) {
-       strcpy(icon, programName);
+      }
+    else if (gameInfo.variant == VariantFalcon)
+      {
        strcpy(title, FALCON);
 #endif
-    } else if (appData.noChessProgram) {
-       strcpy(icon, programName);
+      }
+    else if (appData.noChessProgram)
+      {
        strcpy(title, programName);
-    } else {
-       strcpy(icon, first.tidy);
+      }
+    else
+      {
        snprintf(title,sizeof(title), "%s: %s", programName, first.tidy);
-    }
-    i = 0;
-    XtSetArg(args[i], XtNiconName, (XtArgVal) icon);    i++;
-    XtSetArg(args[i], XtNtitle, (XtArgVal) title);      i++;
-    XtSetValues(shellWidget, args, i);
+      }
+    gtk_window_set_title(GTK_WINDOW(GUI_Window),title);
+
+    return;
 }
 
 
@@ -6975,34 +6602,43 @@ char *HostName()
 #endif /* not HAVE_GETHOSTNAME */
 }
 
-gint delayedEventTimerTag = 0;
+guint delayedEventTimerTag = 0;
 DelayedEventCallback delayedEventCallback = 0;
 
 void
 FireDelayedEvent(data)
      gpointer data;
 {
-    delayedEventTimerTag = 0;
-    delayedEventCallback();
+  /* remove timer */
+  g_source_remove(delayedEventTimerTag);
+  delayedEventTimerTag = 0;
+
+  /* call function */
+  delayedEventCallback();
+
+  return;
 }
 
 void
 ScheduleDelayedEvent(cb, millisec)
-     DelayedEventCallback cb; long millisec;
+     DelayedEventCallback cb; guint millisec;
 {
+    if(delayedEventTimerTag && delayedEventCallback == cb)
+       // [HGM] alive: replace, rather than add or flush identical event
+       g_source_remove(delayedEventTimerTag);
     delayedEventCallback = cb;
-    delayedEventTimerTag =
-      gtk_timeout_add(millisec,(GtkFunction) FireDelayedEvent, NULL);
+    delayedEventTimerTag = g_timeout_add(millisec,(GSourceFunc) FireDelayedEvent, NULL);
+    return;
 }
 
 DelayedEventCallback
 GetDelayedEvent()
 {
-  if (delayedEventTimerTag) 
+  if (delayedEventTimerTag)
     {
       return delayedEventCallback;
-    } 
-  else 
+    }
+  else
     {
       return NULL;
     }
@@ -7011,15 +6647,16 @@ GetDelayedEvent()
 void
 CancelDelayedEvent()
 {
-  if (delayedEventTimerTag) 
+  if (delayedEventTimerTag)
     {
-      gtk_timeout_remove(delayedEventTimerTag);
+      g_source_remove(delayedEventTimerTag);
       delayedEventTimerTag = 0;
     }
+
   return;
 }
 
-gint loadGameTimerTag = 0;
+guint loadGameTimerTag = 0;
 
 int LoadGameTimerRunning()
 {
@@ -7029,7 +6666,7 @@ int LoadGameTimerRunning()
 int StopLoadGameTimer()
 {
     if (loadGameTimerTag != 0) {
-       gtk_timeout_remove(loadGameTimerTag);
+       g_source_remove(loadGameTimerTag);
        loadGameTimerTag = 0;
        return TRUE;
     } else {
@@ -7041,8 +6678,12 @@ void
 LoadGameTimerCallback(data)
      gpointer data;
 {
-    loadGameTimerTag = 0;
-    AutoPlayGameLoop();
+  /* remove timer */
+  g_source_remove(loadGameTimerTag);
+  loadGameTimerTag = 0;
+
+  AutoPlayGameLoop();
+  return;
 }
 
 void
@@ -7050,31 +6691,34 @@ StartLoadGameTimer(millisec)
      long millisec;
 {
   loadGameTimerTag =
-    gtk_timeout_add( millisec, (GtkFunction) LoadGameTimerCallback, NULL);
+    g_timeout_add( millisec, (GSourceFunc) LoadGameTimerCallback, NULL);
+  return;
 }
 
-gint analysisClockTag = 0;
+guint analysisClockTag = 0;
 
-void
+gboolean
 AnalysisClockCallback(data)
      gpointer data;
 {
     if (gameMode == AnalyzeMode || gameMode == AnalyzeFile
-         || appData.icsEngineAnalyze) 
-      { 
+         || appData.icsEngineAnalyze)
+      {
        AnalysisPeriodicEvent(0);
-       StartAnalysisClock();
+       return 1; /* keep on going */
       }
+    return 0; /* stop timer */
 }
 
 void
 StartAnalysisClock()
 {
-    analysisClockTag =
-      gtk_timeout_add( 2000,(GtkFunction) AnalysisClockCallback, NULL);
+  analysisClockTag =
+    g_timeout_add( 2000,(GSourceFunc) AnalysisClockCallback, NULL);
+  return;
 }
 
-gint clockTimerTag = 0;
+guint clockTimerTag = 0;
 
 int ClockTimerRunning()
 {
@@ -7083,13 +6727,13 @@ int ClockTimerRunning()
 
 int StopClockTimer()
 {
-    if (clockTimerTag != 0) 
+    if (clockTimerTag != 0)
       {
-       gtk_timeout_remove(clockTimerTag);
+       g_source_remove(clockTimerTag);
        clockTimerTag = 0;
        return TRUE;
-      } 
-    else 
+      }
+    else
       {
        return FALSE;
       }
@@ -7099,17 +6743,20 @@ void
 ClockTimerCallback(data)
      gpointer data;
 {
-    clockTimerTag = 0;
-    DecrementClocks();
-    return;
+  /* remove timer */
+  g_source_remove(clockTimerTag);
+  clockTimerTag = 0;
+
+  DecrementClocks();
+  return;
 }
 
 void
 StartClockTimer(millisec)
      long millisec;
 {
-    clockTimerTag = gtk_timeout_add(millisec,(GtkFunction) ClockTimerCallback,NULL);
-    return;
+  clockTimerTag = g_timeout_add(millisec,(GSourceFunc) ClockTimerCallback,NULL);
+  return;
 }
 
 void
@@ -7166,7 +6813,7 @@ DisplayWhiteClock(timeRemaining, highlight)
   if(appData.noGUI) return;
 
   DisplayTimerLabel(GUI_Whiteclock, _("White"), timeRemaining, highlight);
-  if (highlight && WindowIcon == BlackIcon) 
+  if (highlight && WindowIcon == BlackIcon)
     {
       WindowIcon = WhiteIcon;
       gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
@@ -7181,7 +6828,7 @@ DisplayBlackClock(timeRemaining, highlight)
     if(appData.noGUI) return;
 
     DisplayTimerLabel(GUI_Blackclock, _("Black"), timeRemaining, highlight);
-    if (highlight && WindowIcon == WhiteIcon) 
+    if (highlight && WindowIcon == WhiteIcon)
       {
         WindowIcon = BlackIcon;
         gtk_window_set_icon(GTK_WINDOW(GUI_Window),WindowIcon);
@@ -7453,51 +7100,75 @@ typedef struct {
     int lineByLine;
     char *unused;
     InputCallback func;
-    XtInputId xid;
+    guint sid;
     char buf[INPUT_SOURCE_BUF_SIZE];
     VOIDSTAR closure;
 } InputSource;
 
 void
-DoInputCallback(closure, source, xid)
-     caddr_t closure;
-     int *source;
-     XtInputId *xid;
+DoInputCallback(io,cond,data)
+     GIOChannel   *io;
+     GIOCondition  cond;
+     gpointer *data;
 {
-    InputSource *is = (InputSource *) closure;
-    int count;
-    int error;
-    char *p, *q;
+  /* read input from one of the input source (for example a chess program, ICS, etc).
+   * and call a function that will handle the input
+   */
 
-    if (is->lineByLine) {
-       count = read(is->fd, is->unused,
-                    INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
-       if (count <= 0) {
-           (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
-           return;
+  int count; /* how many bytes did we read */
+  int error; 
+  char *p, *q;
+  
+  /* All information (callback function, file descriptor, etc) is
+   * saved in an InputSource structure 
+   */
+  InputSource *is = (InputSource *) data; 
+  
+  if (is->lineByLine) 
+    {
+      count = read(is->fd, is->unused,
+                  INPUT_SOURCE_BUF_SIZE - (is->unused - is->buf));
+
+      if (count <= 0) 
+       {
+         (is->func)(is, is->closure, is->buf, count, count ? errno : 0);
+         return;
        }
-       is->unused += count;
-       p = is->buf;
-       while (p < is->unused) {
-           q = memchr(p, '\n', is->unused - p);
-           if (q == NULL) break;
-           q++;
-           (is->func)(is, is->closure, p, q - p, 0);
-           p = q;
+      is->unused += count;
+      p = is->buf;
+      /* break input into lines and call the callback function on each
+       * line 
+       */
+      while (p < is->unused) 
+       {
+         q = memchr(p, '\n', is->unused - p);
+         if (q == NULL) break;
+         q++;
+         (is->func)(is, is->closure, p, q - p, 0);
+         p = q;
        }
-       q = is->buf;
-       while (p < is->unused) {
-           *q++ = *p++;
+      /* remember not yet used part of the buffer */
+      q = is->buf;
+      while (p < is->unused) 
+       {
+         *q++ = *p++;
        }
-       is->unused = q;
-    } else {
-       count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
-       if (count == -1)
-         error = errno;
-       else
-         error = 0;
-       (is->func)(is, is->closure, is->buf, count, error);
+      is->unused = q;
+    }
+  else 
+    {
+      /* read maximum length of input buffer and send the whole buffer
+       * to the callback function 
+       */
+      count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
+      if (count == -1)
+       error = errno;
+      else
+       error = 0;
+      (is->func)(is, is->closure, is->buf, count, error);
     }
+  
+  return;
 }
 
 InputSourceRef AddInputSource(pr, lineByLine, func, closure)
@@ -7507,6 +7178,7 @@ InputSourceRef AddInputSource(pr, lineByLine, func, closure)
      VOIDSTAR closure;
 {
     InputSource *is;
+    GIOChannel *channel;
     ChildProc *cp = (ChildProc *) pr;
 
     is = (InputSource *) calloc(1, sizeof(InputSource));
@@ -7519,14 +7191,23 @@ InputSourceRef AddInputSource(pr, lineByLine, func, closure)
        is->kind = cp->kind;
        is->fd = cp->fdFrom;
     }
-    if (lineByLine) {
-       is->unused = is->buf;
-    }
+    if (lineByLine) 
+      is->unused = is->buf;
+    else
+      is->unused = NULL;
 
-    is->xid = XtAppAddInput(appContext, is->fd,
-                           (XtPointer) (XtInputReadMask),
-                           (XtInputCallbackProc) DoInputCallback,
-                           (XtPointer) is);
+//    is->xid = XtAppAddInput(appContext, is->fd,
+//                         (XtPointer) (XtInputReadMask),
+//                         (XtInputCallbackProc) DoInputCallback,
+//                         (XtPointer) is);
+//
+
+    /* TODO: will this work on windows?*/
+    printf("DEBUG: fd=%d %d\n",is->fd,is);
+
+    channel = g_io_channel_unix_new(is->fd);
+    g_io_channel_set_close_on_unref (channel, TRUE);
+    is->sid = g_io_add_watch(channel, G_IO_IN,(GIOFunc) DoInputCallback, is);
     is->closure = closure;
     return (InputSourceRef) is;
 }
@@ -7537,9 +7218,10 @@ RemoveInputSource(isr)
 {
     InputSource *is = (InputSource *) isr;
 
-    if (is->xid == 0) return;
-    XtRemoveInput(is->xid);
-    is->xid = 0;
+    if (is->sid == 0) return;
+    g_source_remove(is->sid);
+    is->sid = 0;
+    return;
 }
 
 int OutputToProcess(pr, message, count, outError)
@@ -7778,12 +7460,7 @@ FrameDelay (time)
     delay.it_interval.tv_usec =
       delay.it_value.tv_usec = (time % 1000) * 1000;
     setitimer(ITIMER_REAL, &delay, NULL);
-#if 0
-    /* Ugh -- busy-wait! --tpm */
-    while (frameWaiting);
-#else
     while (frameWaiting) pause();
-#endif
     delay.it_interval.tv_sec = delay.it_value.tv_sec = 0;
     delay.it_interval.tv_usec = delay.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL, &delay, NULL);
@@ -7796,7 +7473,7 @@ static void
 FrameDelay (time)
      int time;
 {
-  XSync(xDisplay, False);
+  //  XSync(xDisplay, False);
   if (time > 0)
     usleep(time * 1000);
 }
@@ -7992,7 +7669,7 @@ SelectGCMask(piece, clip, outline, mask)
     else
       source = blPieceGC;
   }
-  XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
+  //  XCopyGC(xDisplay, source, 0xFFFFFFFF, *clip);
 
   /* Outline only used in mono mode and is not modified */
   if (White(piece))
@@ -8009,23 +7686,25 @@ OverlayPiece(piece, clip, outline,  dest)
 
   if (!useImages) {
     /* Draw solid rectangle which will be clipped to shape of piece */
-    XFillRectangle(xDisplay, dest, clip,
-                  0, 0, squareSize, squareSize);
+//    XFillRectangle(xDisplay, dest, clip,
+//                0, 0, squareSize, squareSize)
+;
     if (appData.monoMode)
       /* Also draw outline in contrasting color for black
         on black / white on white cases                */
-      XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
-                0, 0, squareSize, squareSize, 0, 0, 1);
+//      XCopyPlane(xDisplay, *pieceToOutline(piece), dest, outline,
+//              0, 0, squareSize, squareSize, 0, 0, 1)
+;
   } else {
     /* Copy the piece */
     if (White(piece))
       kind = 0;
     else
       kind = 2;
-    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
-             dest, clip,
-             0, 0, squareSize, squareSize,
-             0, 0);
+//    XCopyArea(xDisplay, xpmPieceBitmap[kind][piece],
+//           dest, clip,
+//           0, 0, squareSize, squareSize,
+//           0, 0);
   }
 }
 
@@ -8045,8 +7724,8 @@ BeginAnimation(anim, piece, startColor, start)
   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);
+//  SelectGCMask(piece, &anim->pieceGC, &anim->outlineGC, &mask);
+//  XSetClipMask(xDisplay, anim->pieceGC, mask);
 }
 
 static void
@@ -8061,45 +7740,46 @@ AnimationFrame(anim, frame, piece)
   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);
+//  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);
+//    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);
+//      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);
+//    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);
+//  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);
+//  XCopyArea(xDisplay, anim->newBuf, xBoardWindow, anim->blitGC,
+//             0, 0, squareSize, squareSize,
+//             frame->x, frame->y);
 }
 
 static void
@@ -8117,15 +7797,16 @@ EndAnimation (anim, finish)
   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);
+//      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);
+//    XCopyArea(xDisplay, anim->saveBuf, xBoardWindow, anim->blitGC,
+//             0, 0, squareSize, squareSize,
+//             anim->prevFrame.x, anim->prevFrame.y);
   }
 }
 
@@ -8232,19 +7913,10 @@ DragPieceBegin(x, y)
     ScreenSquare(boardX, boardY, &corner, &color);
     player.startSquare  = corner;
     player.startColor   = color;
-#if 0
-    /* Start from exactly where the piece is.  This can be confusing
-       if you start dragging far from the center of the square; most
-       or all of the piece can be over a different square from the one
-       the mouse pointer is in. */
-    player.mouseDelta.x = x - corner.x;
-    player.mouseDelta.y = y - corner.y;
-#else
     /* As soon as we start dragging, the piece will jump slightly to
        be centered over the mouse pointer. */
     player.mouseDelta.x = squareSize/2;
     player.mouseDelta.y = squareSize/2;
-#endif
     /* Initialise animation */
     player.dragPiece = PieceForSquare(boardX, boardY);
     /* Sanity check */
@@ -8256,9 +7928,9 @@ DragPieceBegin(x, y)
           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
+//           XCopyArea(xDisplay, xBoardWindow, player.saveBuf, player.blitGC,
+//                  corner.x, corner.y, squareSize, squareSize,
+//                  0, 0); // [HGM] zh: unstack in stead of grab
        damage[boardY][boardX] = True;
     } else {
        player.dragActive = False;