static void DefColor P((int n));
static void AdjustColor P((int i));
+static char oldPieceDir[MSG_SIZ];
+
static int
BoardOptionsOK (int n)
{
if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap;
- useImages = useImageSqs = 0;
- InitDrawingParams();
+ InitDrawingParams(strcmp(oldPieceDir, appData.pieceDirectory));
InitDrawingSizes(-1, 0);
DrawPosition(True, NULL);
return 1;
{ 0, 0, 0, NULL, (void*) &appData.useBitmaps, "", NULL, CheckBox, N_("Use Board Textures") },
{ 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, ".xpm", NULL, FileName, N_("Light-Squares Texture File:") },
{ 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, ".xpm", NULL, FileName, N_("Dark-Squares Texture File:") },
-{ 0, 0, 0, NULL, (void*) &appData.bitmapDirectory, "", NULL, PathName, N_("Directory with Bitmap Pieces:") },
-{ 0, 0, 0, NULL, (void*) &appData.pixmapDirectory, "", NULL, PathName, N_("Directory with Pixmap Pieces:") },
+{ 0, 0, 0, NULL, (void*) &appData.trueColors, "", NULL, CheckBox, N_("Use external piece bitmaps with their own colors") },
+{ 0, 0, 0, NULL, (void*) &appData.pieceDirectory, "", NULL, PathName, N_("Directory with Pieces Images:") },
{ 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" }
};
void
BoardOptionsProc ()
{
+ strncpy(oldPieceDir, appData.pieceDirectory, MSG_SIZ-1); // to see if it changed
GenericPopUp(boardOptions, _("Board Options"), TransientDlg, BoardWindow, MODAL, 0);
}
if((p = icsTextMenuString) == NULL) return;
do {
q = r = p; while(*p && *p != ';') p++;
+ if(textOptions[i].name == NULL) textOptions[i].name = (char*) malloc(MSG_SIZ);
for(j=0; j<p-q; j++) textOptions[i].name[j] = *r++;
textOptions[i].name[j++] = 0;
if(!*p) break;
// end of borrowed code
Option boxOptions[] = {
-{ 30, 0, 400, NULL, (void*) &icsText, "", NULL, TextBox, "" },
-{ 0,SAME_ROW | NO_OK, 0, NULL, NULL, "", NULL, EndMark , "" }
+{ 30, T_TOP, 400, NULL, (void*) &icsText, "", NULL, TextBox, "" },
+{ 0, NO_OK, 0, NULL, NULL, "", NULL, EndMark , "" }
};
void
}
SetWidgetText(&boxOptions[0], text, TextMenuDlg);
SetInsertPos(&boxOptions[0], pos);
+ HardSetFocus(&boxOptions[0]);
}
void
static int TypeInOK P((int n));
Option typeOptions[] = {
-{ 30, 0, 400, NULL, (void*) &icsText, "", NULL, TextBox, "" },
-{ 0, SAME_ROW | NO_OK, 0, NULL, (void*) &TypeInOK, "", NULL, EndMark , "" }
+{ 30, T_TOP, 400, NULL, (void*) &icsText, "", NULL, TextBox, "" },
+{ 0, NO_OK, 0, NULL, (void*) &TypeInOK, "", NULL, EndMark , "" }
};
static int
//---------------------------- Chat Windows ----------------------------------------------
+static char *line, *memo, *partner, *texts[MAX_CHAT], dirty[MAX_CHAT];
+static int activePartner;
+
+void ChatSwitch P((int n));
+int ChatOK P((int n));
+
+Option chatOptions[] = {
+{ 0, T_TOP, 100, NULL, (void*) &partner, NULL, NULL, TextBox, N_("Chat partner:") },
+{ 1, SAME_ROW|TT, 75, NULL, (void*) &ChatSwitch, NULL, NULL, Button, "" },
+{ 2, SAME_ROW|TT, 75, NULL, (void*) &ChatSwitch, NULL, NULL, Button, "" },
+{ 3, SAME_ROW|TT, 75, NULL, (void*) &ChatSwitch, NULL, NULL, Button, "" },
+{ 4, SAME_ROW|TT, 75, NULL, (void*) &ChatSwitch, NULL, NULL, Button, "" },
+{ 100, T_VSCRL | T_FILL | T_WRAP | T_TOP, 510, NULL, (void*) &memo, NULL, NULL, TextBox, "" },
+{ 0, 0, 510, NULL, (void*) &line, NULL, NULL, TextBox, "" },
+{ 0, NO_OK|SAME_ROW, 0, NULL, (void*) &ChatOK, NULL, NULL, EndMark , "" }
+};
+
void
OutputChatMessage (int partner, char *mess)
{
- return; // dummy
+ char *p = texts[partner];
+ int len = strlen(mess) + 1;
+
+ if(p) len += strlen(p);
+ texts[partner] = (char*) malloc(len);
+ snprintf(texts[partner], len, "%s%s", p ? p : "", mess);
+ FREE(p);
+ if(partner == activePartner) {
+ AppendText(&chatOptions[5], mess);
+ SetInsertPos(&chatOptions[5], len-2);
+ } else {
+ SetColor("#FFC000", &chatOptions[partner + (partner < activePartner)]);
+ dirty[partner] = 1;
+ }
+}
+
+int
+ChatOK (int n)
+{ // can only be called through <Enter> in chat-partner text-edit, as there is no OK button
+ char buf[MSG_SIZ];
+ if(!partner || strcmp(partner, chatPartner[activePartner])) {
+ safeStrCpy(chatPartner[activePartner], partner, MSG_SIZ);
+ SetWidgetText(&chatOptions[5], "", -1); // clear text if we alter partner
+ SetWidgetText(&chatOptions[6], "", ChatDlg); // clear text if we alter partner
+ HardSetFocus(&chatOptions[6]);
+ }
+ if(line[0]) { // something was typed
+ SetWidgetText(&chatOptions[6], "", ChatDlg);
+ // from here on it could be back-end
+ if(line[strlen(line)-1] == '\n') line[strlen(line)-1] = NULLCHAR;
+ SaveInHistory(line);
+ if(!strcmp("whispers", chatPartner[activePartner]))
+ snprintf(buf, MSG_SIZ, "whisper %s\n", line); // WHISPER box uses "whisper" to send
+ else if(!strcmp("shouts", chatPartner[activePartner]))
+ snprintf(buf, MSG_SIZ, "shout %s\n", line); // SHOUT box uses "shout" to send
+ else {
+ if(!atoi(chatPartner[activePartner])) {
+ snprintf(buf, MSG_SIZ, "> %s\n", line); // echo only tells to handle, not channel
+ OutputChatMessage(activePartner, buf);
+ snprintf(buf, MSG_SIZ, "xtell %s %s\n", chatPartner[activePartner], line);
+ } else
+ snprintf(buf, MSG_SIZ, "tell %s %s\n", chatPartner[activePartner], line);
+ }
+ SendToICS(buf);
+ }
+ return FALSE; // never pop down
+}
+
+void
+ChatSwitch (int n)
+{
+ int i, j;
+ if(n <= activePartner) n--;
+ activePartner = n;
+ if(!texts[n]) texts[n] = strdup("");
+ dirty[n] = 0;
+ SetWidgetText(&chatOptions[5], texts[n], ChatDlg);
+ SetInsertPos(&chatOptions[5], strlen(texts[n]));
+ SetWidgetText(&chatOptions[0], chatPartner[n], ChatDlg);
+ for(i=j=0; i<MAX_CHAT; i++) {
+ if(i == activePartner) continue;
+ SetWidgetLabel(&chatOptions[++j], chatPartner[i]);
+ SetColor(dirty[i] ? "#FFC000" : "#FFFFFF", &chatOptions[j]);
+ }
+ SetWidgetText(&chatOptions[6], "", ChatDlg);
+ HardSetFocus(&chatOptions[6]);
+}
+
+void
+ChatProc ()
+{
+ if(GenericPopUp(chatOptions, _("Chat box"), ChatDlg, BoardWindow, NONMODAL, 0))
+ AddHandler(&chatOptions[0], 2), AddHandler(&chatOptions[6], 2); // treats return as OK
+ MarkMenu("View.OpenChatWindow", ChatDlg);
}
//--------------------------------- Game-List options dialog ------------------------------------------
snprintf(buf, sizeof(buf), "%s: %s", message, strerror(error));
message = buf;
}
- if (appData.popupExitMessage && boardWidget && XtIsRealized(boardWidget)) {
- ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
- } else {
- ExitEvent(status);
+ if(mainOptions[W_BOARD].handle) {
+ if (appData.popupExitMessage) {
+ ErrorPopUp(status ? _("Fatal Error") : _("Exiting"), message, TRUE);
+ } else {
+ ExitEvent(status);
+ }
}
}
static Option *Exp P((int n, int x, int y));
void MenuCallback P((int n));
void SizeKludge P((int n));
+static Option *LogoW P((int n, int x, int y));
+static Option *LogoB P((int n, int x, int y));
static int pmFromX = -1, pmFromY = -1;
+void *userLogo;
+
+void
+DisplayLogos (Option *w1, Option *w2)
+{
+ void *whiteLogo = first.programLogo, *blackLogo = second.programLogo;
+ if(appData.autoLogo) {
+
+ switch(gameMode) { // pick logos based on game mode
+ case IcsObserving:
+ whiteLogo = second.programLogo; // ICS logo
+ blackLogo = second.programLogo;
+ default:
+ break;
+ case IcsPlayingWhite:
+ if(!appData.zippyPlay) whiteLogo = userLogo;
+ blackLogo = second.programLogo; // ICS logo
+ break;
+ case IcsPlayingBlack:
+ whiteLogo = second.programLogo; // ICS logo
+ blackLogo = appData.zippyPlay ? first.programLogo : userLogo;
+ break;
+ case TwoMachinesPlay:
+ if(first.twoMachinesColor[0] == 'b') {
+ whiteLogo = second.programLogo;
+ blackLogo = first.programLogo;
+ }
+ break;
+ case MachinePlaysWhite:
+ blackLogo = userLogo;
+ break;
+ case MachinePlaysBlack:
+ whiteLogo = userLogo;
+ blackLogo = first.programLogo;
+ }
+ }
+ DrawLogo(w1, whiteLogo);
+ DrawLogo(w2, blackLogo);
+}
static void
PMSelect (int n)
{ 0, COMBO_CALLBACK, 0, NULL, (void*)&MenuCallback, NULL, NULL, DropDown, N_("Help") },
{ 0, 0, 0, NULL, (void*)&SizeKludge, "", NULL, BoxEnd, "" },
{ 0, LR|T2T|BORDER|SAME_ROW, 0, NULL, NULL, "", NULL, Label, "1" }, // optional title in window
-{ 0, L2L|T2T, 200, NULL, (void*) &CCB, NULL, NULL, Label, "White" }, // white clock
-{ 0, R2R|T2T|SAME_ROW, 200, NULL, (void*) &CCB, NULL, NULL, Label, "Black" }, // black clock
+{ 50, LL|TT, 100, NULL, (void*) &LogoW, NULL, NULL, -1, "LogoW" }, // white logo
+{ 0, L2L|T2T, 200, NULL, (void*) &CCB, NULL, NULL, Label, "White" }, // white clock
+{ 0, R2R|T2T|SAME_ROW, 200, NULL, (void*) &CCB, NULL, NULL, Label, "Black" }, // black clock
+{ 50, RR|TT|SAME_ROW, 100, NULL, (void*) &LogoB, NULL, NULL, -1, "LogoB" }, // black logo
{ 0, LR|T2T|BORDER, 401, NULL, NULL, "", NULL, -1, "2" }, // backup for title in window (if no room for other)
{ 0, LR|T2T|BORDER, 270, NULL, NULL, "", NULL, Label, "message" }, // message field
{ 0, RR|TT|SAME_ROW, 125, NULL, NULL, "", NULL, BoxBegin, "" }, // (optional) button bar
{ 0, SAME_ROW, 0, NULL, (void*) &ForwardEvent, NULL, NULL, Button, N_(">") },
{ 0, SAME_ROW, 0, NULL, (void*) &ToEndEvent, NULL, NULL, Button, N_(">>") },
{ 0, 0, 0, NULL, NULL, "", NULL, BoxEnd, "" },
-{ 401, LR|TT, 401, NULL, (char*) &Exp, NULL, NULL, Graph, "shadow board" }, // board
+{ 401, LR|TB, 401, NULL, (char*) &Exp, NULL, NULL, Graph, "shadow board" }, // board
{ 2, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, pieceMenuStrings[0], PopUp, "menuW" },
{ 2, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, pieceMenuStrings[1], PopUp, "menuB" },
{ -1, COMBO_CALLBACK, 0, NULL, (void*) &PMSelect, NULL, dropMenuStrings, PopUp, "menuD" },
{ 0, NO_OK, 0, NULL, NULL, "", NULL, EndMark , "" }
};
+Option *
+LogoW (int n, int x, int y)
+{
+ if(n == 10) DisplayLogos(&mainOptions[W_WHITE-1], NULL);
+ return NULL;
+}
+
+Option *
+LogoB (int n, int x, int y)
+{
+ if(n == 10) DisplayLogos(NULL, &mainOptions[W_BLACK+1]);
+ return NULL;
+}
+
void
SizeKludge (int n)
{ // callback called by GenericPopUp immediately after sizing the menu bar
static Option *
Exp (int n, int x, int y)
{
- static int but1, but3;
- int menuNr = -3;
+ static int but1, but3, oldW, oldH;
+ int menuNr = -3, sizing;
if(n == 0) { // motion
if(SeekGraphClick(Press, x, y, 1)) return NULL;
case -2: shiftKey = !shiftKey;
case -3: menuNr = RightClick(Release, x, y, &pmFromX, &pmFromY), but3 = 0; break;
case 10:
+ sizing = (oldW != x || oldH != y);
+ oldW = x; oldH = y;
+ InitDrawingHandle(mainOptions + W_BOARD);
+ if(sizing) return NULL; // don't redraw while sizing
DrawPosition(True, NULL);
default:
return NULL;
Option *
BoardPopUp (int squareSize, int lineGap, void *clockFontThingy)
{
- int i, size = BOARD_WIDTH*(squareSize + lineGap) + lineGap;
+ int i, size = BOARD_WIDTH*(squareSize + lineGap) + lineGap, logo = appData.logoSize;
mainOptions[W_WHITE].choice = (char**) clockFontThingy;
mainOptions[W_BLACK].choice = (char**) clockFontThingy;
mainOptions[W_BOARD].value = BOARD_HEIGHT*(squareSize + lineGap) + lineGap;
mainOptions[W_BOARD].max = mainOptions[W_SMALL].max = size; // board size
mainOptions[W_SMALL].max = size - 2; // board title (subtract border!)
mainOptions[W_BLACK].max = mainOptions[W_WHITE].max = size/2-3; // clock width
- mainOptions[W_MESSG].max = appData.showButtonBar ? size-130 : size-2; // message
+ mainOptions[W_MESSG].max = appData.showButtonBar ? size-135 : size-2; // message
mainOptions[W_MENU].max = size-40; // menu bar
mainOptions[W_TITLE].type = appData.titleInWindow ? Label : -1 ;
+ if(logo && logo <= size/4) { // Activate logos
+ mainOptions[W_WHITE-1].type = mainOptions[W_BLACK+1].type = Graph;
+ mainOptions[W_WHITE-1].max = mainOptions[W_BLACK+1].max = logo;
+ mainOptions[W_WHITE-1].value= mainOptions[W_BLACK+1].value= logo/2;
+ mainOptions[W_WHITE].min |= SAME_ROW;
+ mainOptions[W_WHITE].max = mainOptions[W_BLACK].max -= logo + 4;
+ mainOptions[W_WHITE].name = mainOptions[W_BLACK].name = "Double\nHeight";
+ }
if(!appData.showButtonBar) for(i=W_BUTTON; i<W_BOARD; i++) mainOptions[i].type = -1;
for(i=0; i<8; i++) mainOptions[i+1].choice = (char**) menuBar[i].mi;
GenericPopUp(mainOptions, "XBoard", BoardWindow, BoardWindow, NONMODAL, 1);
}
if(!fileName[0]) return FALSE; // refuse OK when no file
if(!savMode[0]) { // browsing for name only (dialog Browse button)
- snprintf(title, MSG_SIZ, "%s/%s", curDir, fileName);
+ if(fileName[0] == '/') // We already had a path name
+ snprintf(title, MSG_SIZ, "%s", fileName);
+ else
+ snprintf(title, MSG_SIZ, "%s/%s", curDir, fileName);
SetWidgetText((Option*) savFP, title, TransientDlg);
currentCps = savCps; // could return to Engine Settings dialog!
return TRUE;