changes from H.G. Muller; version 4.3.16
[xboard.git] / xboard.c
index 54718f3..54c457e 100644 (file)
--- a/xboard.c
+++ b/xboard.c
@@ -423,11 +423,14 @@ void EngineMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
 void UciMenuProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
 void TimeControlProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
 void NewVariantProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void FirstSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
+void SecondSettingsProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));\r
 void ShufflePopDown P(());\r
 void EnginePopDown P(());\r
 void UciPopDown P(());\r
 void TimeControlPopDown P(());\r
 void NewVariantPopDown P(());\r
+void SettingsPopDown P(());\r
 /*\r
 * XBoard depends on Xt R4 or higher\r
 */\r
@@ -606,7 +609,9 @@ MenuItem optionsMenu[] = {
     {"Flip View", FlipViewProc},\r
     {"----", NothingProc},    \r
     {"Adjudications ...", EngineMenuProc},    \r
-    {"Engine Settings ...", UciMenuProc},    \r
+    {"General Settings ...", UciMenuProc},    \r
+    {"Engine #1 Settings ...", FirstSettingsProc},    \r
+    {"Engine #2 Settings ...", SecondSettingsProc},    \r
     {"Time Control ...", TimeControlProc},    \r
     {"----", NothingProc},    \r
     {"Always Queen", AlwaysQueenProc},\r
@@ -1287,6 +1292,9 @@ XtResource clientResources[] = {
     { "smpCores", "smpCores", XtRInt,\r
        sizeof(int), XtOffset(AppDataPtr, smpCores),\r
        XtRImmediate, (XtPointer) 1},\r
+    { "niceEngines", "niceEngines", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, niceEngines),\r
+       XtRImmediate, (XtPointer) 0},\r
 
     // [HGM] Winboard_x UCI options\r
     { "firstIsUCI", "firstIsUCI", XtRBoolean,\r
@@ -1319,6 +1327,12 @@ XtResource clientResources[] = {
     { "defaultPathEGTB", "defaultPathEGTB", XtRString,\r
        sizeof(String), XtOffset(AppDataPtr, defaultPathEGTB),\r
        XtRImmediate, (XtPointer) "/usr/local/share/egtb"},\r
+    { "delayBeforeQuit", "delayBeforeQuit", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, delayBeforeQuit),\r
+       XtRImmediate, (XtPointer) 0},\r
+    { "delayAfterQuit", "delayAfterQuit", XtRInt,\r
+       sizeof(int), XtOffset(AppDataPtr, delayAfterQuit),\r
+       XtRImmediate, (XtPointer) 0},\r
 };\r
 \r
 XrmOptionDescRec shellOptions[] = {\r
@@ -1668,6 +1682,9 @@ XrmOptionDescRec shellOptions[] = {
     { "-smpCores", "smpCores", XrmoptionSepArg, NULL }, \r
     { "-sameColorGames", "sameColorGames", XrmoptionSepArg, NULL }, \r
     { "-rewindIndex", "rewindIndex", XrmoptionSepArg, NULL }, \r
+    { "-niceEngines", "niceEngines", XrmoptionSepArg, NULL }, \r
+    { "-delayBeforeQuit", "delayBeforeQuit", XrmoptionSepArg, NULL }, \r
+    { "-delayAfterQuit", "delayAfterQuit", XrmoptionSepArg, NULL }, \r
 };\r
 \r
 \r
@@ -1791,6 +1808,7 @@ XtActionsRec boardActions[] = {
     { "UciPopDown", (XtActionProc) UciPopDown },\r
     { "TimeControlPopDown", (XtActionProc) TimeControlPopDown },\r
     { "NewVariantPopDown", (XtActionProc) NewVariantPopDown },\r
+    { "SettingsPopDown", (XtActionProc) SettingsPopDown },\r
 };\r
      \r
 char globalTranslations[] =\r
@@ -7997,7 +8015,9 @@ int StartChildProcess(cmdLine, dir, pr)
        if (dir[0] != NULLCHAR && chdir(dir) != 0) {\r
            perror(dir);\r
            exit(1);\r
-       }\r
+       }
+
+       nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc\r
 \r
         execvp(argv[0], argv);\r
        \r
@@ -8019,22 +8039,37 @@ int StartChildProcess(cmdLine, dir, pr)
     return 0;\r
 }\r
 \r
+// [HGM] kill: implement the 'hard killing' of AS's Winboard_x\r
+static RETSIGTYPE AlarmCallBack(int n)\r
+{\r
+    return;\r
+}\r
+\r
 void\r
-DestroyChildProcess(pr, signal)\r
+DestroyChildProcess(pr, signalType)\r
      ProcRef pr;\r
-     int signal;\r
+     int signalType;\r
 {\r
     ChildProc *cp = (ChildProc *) pr;\r
 \r
     if (cp->kind != CPReal) return;\r
     cp->kind = CPNone;\r
-    if (signal) {\r
-      kill(cp->pid, SIGTERM);\r
+    if (signalType == 10) { // [HGM] kill: if it does not terminate in 3 sec, kill\r
+       signal(SIGALRM, AlarmCallBack);\r
+       alarm(3);\r
+       if(wait((int *) 0) == -1) { // process does not terminate on its own accord\r
+           kill(cp->pid, SIGKILL); // kill it forcefully\r
+           wait((int *) 0);        // and wait again\r
+       }\r
+    } else {\r
+       if (signalType) {\r
+           kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: use hard kill if so requested\r
+       }\r
+       /* Process is exiting either because of the kill or because of\r
+          a quit command sent by the backend; either way, wait for it to die.\r
+       */\r
+       wait((int *) 0);\r
     }\r
-    /* Process is exiting either because of the kill or because of\r
-       a quit command sent by the backend; either way, wait for it to die.\r
-    */\r
-    wait((int *) 0);\r
     close(cp->fdFrom);\r
     close(cp->fdTo);\r
 }\r