/* popup.c Copyright (C) 1994 Lambert Klasen & Detlef Steuer klasen@asterix.uni-muenster.de steuer@amadeus.statistik.uni-dortmund.de This file is free source code; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See COPYING for more details. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "xgammon.h" #include "gammon.h" Widget popup_shell; /* diawin.c */ extern void CreateDialogWindow(); extern void CreateTournamentWindow(); /* drawing.c */ extern void DrawDoubler(); /* xgammon.c */ extern void Quit (); extern void MenuSelect (); extern void restart (); void CreateXGammonPopup (); void ShowComputerAnswerToDoubling (); int DoublePopup (); void Info (); void CreateXGammonPopup (X11SET *X11Set) { Arg from[1]; int i; char *menu1_names[10]; char *menu2_names[10]; char *menu3_names[10]; if (!gammon_resource.other_display) { menu1_names[0] = "save position "; menu1_names[1] = "load position "; menu1_names[2] = "save game "; menu1_names[3] = "load game "; menu1_names[4] = "save as .."; menu1_names[5] = "load .."; menu1_names[6] = NULL; menu2_names[0] = "restart "; menu2_names[1] = "human vs. compi"; menu2_names[2] = "compi vs. compi"; menu2_names[3] = "human vs. human"; menu2_names[4] = "computer finish"; menu2_names[5] = "rollout"; menu2_names[6] = "edit position"; menu2_names[7] = "mail dump"; menu2_names[8] = "replay game"; menu2_names[9] = NULL; } else { menu1_names[0] = "save position "; menu1_names[1] = "load position "; menu1_names[2] = "save game "; menu1_names[3] = "load game "; menu1_names[4] = "save as .."; menu1_names[5] = "load .."; menu1_names[6] = NULL; menu2_names[0] = "restart "; menu2_names[1] = "mail dump"; menu2_names[2] = NULL; } menu3_names[0] = "resign normal"; menu3_names[1] = "resign gammon"; menu3_names[2] = "resign backgammon"; menu3_names[3] = "undo move "; menu3_names[4] = NULL; X11Set->button_shell = XtCreatePopupShell ("XGammon-Buttons", topLevelShellWidgetClass, X11Set->toplevel, NULL, 0); X11Set->form = XtCreateManagedWidget ("form", formWidgetClass, X11Set->button_shell, NULL, 0); /* some buttons to push */ X11Set->quit = XtCreateManagedWidget ("quit", commandWidgetClass, X11Set->form, NULL, 0); XtAddCallback (X11Set->quit, XtNcallback, Quit, NULL); /* the file menu */ XtSetArg (from[0], XtNfromHoriz, X11Set->quit); X11Set->file_button = XtCreateManagedWidget ("file", menuButtonWidgetClass, X11Set->form, from, 1); X11Set->menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, X11Set->file_button, NULL, 0); for (i = 0; menu1_names[i]; i++) { X11Set->entry = XtCreateManagedWidget (menu1_names[i], smeBSBObjectClass, X11Set->menu, NULL, 0); XtAddCallback (X11Set->entry, XtNcallback, MenuSelect, NULL); } /* the option menu */ XtSetArg (from[0], XtNfromHoriz, X11Set->file_button); X11Set->option_button = XtCreateManagedWidget ("options", menuButtonWidgetClass, X11Set->form, from, 1); X11Set->menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, X11Set->option_button, NULL, 0); for (i = 0; menu2_names[i]; i++) { X11Set->entry = XtCreateManagedWidget (menu2_names[i], smeBSBObjectClass, X11Set->menu, NULL, 0); XtAddCallback (X11Set->entry, XtNcallback, MenuSelect, NULL); } /* the game menu */ XtSetArg (from[0], XtNfromHoriz, X11Set->option_button); X11Set->game_button = XtCreateManagedWidget ("game", menuButtonWidgetClass, X11Set->form, from, 1); X11Set->menu = XtCreatePopupShell ("menu", simpleMenuWidgetClass, X11Set->game_button, NULL, 0); for (i = 0; menu3_names[i]; i++) { X11Set->entry = XtCreateManagedWidget (menu3_names[i], smeBSBObjectClass, X11Set->menu, NULL, 0); XtAddCallback (X11Set->entry, XtNcallback, MenuSelect, NULL); } /* finally the textwidgets to display some */ CreateTournamentWindow (X11Set); CreateDialogWindow (X11Set); } void ShowComputerAnswerToDoubling (int accept) { char *label_string; Arg arg[5]; Position x, y; Widget toplevel; Widget form, label, ok; if (gammon_resource.other_display) toplevel = Player[turn-1].X11Set.toplevel; else toplevel = Player[0].X11Set.toplevel; /* first here this message */ sprintf (add_text, "%s doubles.\n", Player[turn-1].name); AppendDialogText (LOWER, add_text); XtSetArg (arg[0], XtNx, &x); XtSetArg (arg[1], XtNy, &y); XtGetValues (toplevel, arg, 2); x += width/2; /* in the middle of the board */ y += height/2; XtSetArg (arg[0], XtNx, x); XtSetArg (arg[1], XtNy, y); popup_shell = XtCreatePopupShell ("doubling", transientShellWidgetClass, toplevel, arg, 2); form = XtCreateManagedWidget ("form", formWidgetClass, popup_shell, NULL, 0); if (accept) label_string = " I accept doubling "; else label_string = " I resign "; XtSetArg (arg[0], XtNlabel, label_string); label = XtCreateManagedWidget ("label", labelWidgetClass, form, arg, 1); /* command button is dummmy */ XtSetArg (arg[0], XtNfromVert, label); ok = XtCreateManagedWidget ("ok", commandWidgetClass, form, arg, 1); XtPopup (popup_shell, XtGrabExclusive); WaitForEvent(ButtonRelease); if (accept) { doubler.value *= 2; DrawDoubler (doubler.value, doubler.owner); sprintf (add_text, "%s accepts the double.\n\n", Player[other-1].name); } else { sprintf (add_text, "%s gives up.\n\n", Player[other-1].name); } AppendDialogText (LOWER, add_text); XtPopdown (popup_shell); } /* DoublePopup() this popup is alaways called, when the answer of a human player is expected, the difference in layout is checked via the Player[].type. then the function simply waits for a button event. */ int DoublePopup (void) { Widget toplevel; Widget form, label, resign, accept; Arg arg[2]; Position x, y; char label_string[128]; int ret; if (gammon_resource.other_display) toplevel = Player[other-1].X11Set.toplevel; else toplevel = Player[0].X11Set.toplevel; /* first from here this message */ sprintf (add_text,"%s doubles.\n", Player[turn-1].name); AppendDialogText (LOWER, add_text); XtSetArg(arg[0], XtNx, &x); XtSetArg(arg[1], XtNy, &y); XtGetValues(toplevel, arg, 2); x += width/2; /* in the middle of the board */ y += height/2; XtSetArg(arg[0], XtNx, x); XtSetArg(arg[1], XtNy, y); popup_shell = XtCreatePopupShell ("doubling", transientShellWidgetClass, toplevel, arg, 2); form = XtCreateManagedWidget ("form", formWidgetClass, popup_shell, NULL, 0); if (Player[0].type == HUMAN && Player[1].type == HUMAN) { if (turn == BLACK) strcpy (label_string, " white player: \n do you accept doubling? "); else strcpy (label_string, " black player: \n do you accept doubling? "); } else { strcpy (label_string, " I'd like to double \n do you accept? "); } XtSetArg (arg[0], XtNlabel, label_string); label = XtCreateManagedWidget ("label", labelWidgetClass, form, arg, 1); XtSetArg (arg[0], XtNfromVert, label); resign = XtCreateManagedWidget ("resign", commandWidgetClass, form, arg, 1); XtSetArg (arg[1], XtNfromHoriz, resign); accept = XtCreateManagedWidget ("accept", commandWidgetClass, form, arg, 2); XtPopup(popup_shell, XtGrabExclusive); /* once again an event problem, cause of idontknowwhat or somelikethat, the Callback functions are too slow, to get an event and process it, before the event loop looks for the next one. So, you have to popdown the shell two times or to try this bullshit here. (can't do better, yet) any event other than pressing resign button is accept. */ while (1) { XEvent event; XtAppNextEvent (app_con, &event); if (event.type == ButtonRelease) { if (event.xbutton.window == XtWindow (resign)) { sprintf (add_text, "%s gives up. %s wins %d point\n\n", Player[other-1].name, Player[turn-1].name, doubler.value); AppendDialogText (LOWER, add_text); XtDispatchEvent (&event); ret = RESIGN; break; } else if (event.xbutton.window == XtWindow (accept)) { doubler.value *= 2; DrawDoubler (doubler.value, doubler.owner); sprintf (add_text,"%s accepts the double.\n\n", Player[other-1].name); AppendDialogText (LOWER, add_text); XtDispatchEvent (&event); ret = ACCEPT; break; } } XtDispatchEvent (&event); } XtPopdown (popup_shell); return ret; } void Info (char *message) { Arg arg[3]; Position x, y; Widget toplevel = Player[turn-1].X11Set.toplevel; Widget info_form, info_label, down; XtSetArg (arg[0], XtNx, &x); XtSetArg (arg[1], XtNy, &y); XtGetValues (toplevel, arg, 2); x += width/4; /* almost the center */ y += height/2; XtSetArg (arg[0], XtNx, x); XtSetArg (arg[1], XtNy, y); popup_shell = XtCreatePopupShell ("Info", transientShellWidgetClass, toplevel, arg, 2); info_form = XtCreateManagedWidget ("info_form", formWidgetClass, popup_shell, NULL, 0); XtSetArg (arg[0], XtNlabel, message); info_label = XtCreateManagedWidget ("info_label", labelWidgetClass, info_form, arg, 1); XtSetArg (arg[0], XtNfromVert, info_label); down = XtCreateManagedWidget ("ok", commandWidgetClass, info_form, arg, 1); XtPopup (popup_shell, XtGrabExclusive); while (1) { XEvent event; XtAppNextEvent (app_con, &event); if (event.type == KeyPress) { KeySym k; Modifiers m; k = XtGetActionKeysym (&event, &m); if (k == ' ' || k == XK_Return) { XtPopdown (popup_shell); XtDispatchEvent (&event); break; } } else if (event.type == ButtonRelease && event.xbutton.window == XtWindow (down)) { XtPopdown (popup_shell); XtDispatchEvent (&event); break; } XtDispatchEvent (&event); } }