You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

297 lines
8.0 KiB

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "x11.h"
  4. #include "x11-motif.h"
  5. #include <Xm/Xm.h>
  6. #include <Xm/Label.h>
  7. #include <Xm/RowColumn.h>
  8. #include <Xm/DrawingA.h>
  9. #include <Xm/PushB.h>
  10. #include <Xm/CascadeB.h>
  11. #include <Xm/MessageB.h>
  12. #include <Xm/SelectioB.h>
  13. #include <Xm/Text.h>
  14. #include "util.h"
  15. #include "Game.h"
  16. #include "UI.h"
  17. static Widget base, menubar, field;
  18. static Widget dialogs[DIALOG_MAX + 1];
  19. static Widget pausebutton;
  20. static void
  21. x11_motif_popup_dialog(int index) {
  22. x11_popup(dialogs[index]);
  23. }
  24. static void
  25. popup(Widget w, XtPointer client_data, XtPointer call_data) {
  26. UNUSED(w);
  27. UNUSED(call_data);
  28. x11_motif_popup_dialog((int)client_data);
  29. }
  30. static Widget
  31. new_menu_item(Widget pulldown, int dialog) {
  32. Widget menu_item = XtCreateManagedWidget(UI_menu_string(dialog),
  33. xmPushButtonWidgetClass,
  34. pulldown, NULL, 0);
  35. XtAddCallback(menu_item, XmNactivateCallback, popup, (void *) dialog);
  36. return menu_item;
  37. }
  38. static Widget
  39. CreateMenuBar(const char *name, Widget parent) {
  40. Widget menubar, pulldown;
  41. Widget game_menu, info_menu;
  42. menubar = XmCreateMenuBar(parent, (char *)name, NULL, 0);
  43. XtManageChild(menubar);
  44. pulldown = XmCreatePulldownMenu(menubar, "menu", NULL, 0);
  45. game_menu = XtVaCreateManagedWidget("Game",
  46. xmCascadeButtonWidgetClass,
  47. menubar, XmNsubMenuId,
  48. pulldown, NULL);
  49. new_menu_item(pulldown, DIALOG_NEWGAME);
  50. pausebutton = new_menu_item(pulldown, DIALOG_PAUSEGAME);
  51. new_menu_item(pulldown, DIALOG_WARPLEVEL);
  52. new_menu_item(pulldown, DIALOG_HIGHSCORE);
  53. new_menu_item(pulldown, DIALOG_QUITGAME);
  54. pulldown = XmCreatePulldownMenu(menubar, "menu", NULL, 0);
  55. info_menu = XtVaCreateManagedWidget("Info",
  56. xmCascadeButtonWidgetClass,
  57. menubar, XmNsubMenuId,
  58. pulldown, NULL);
  59. new_menu_item(pulldown, DIALOG_STORY);
  60. new_menu_item(pulldown, DIALOG_RULES);
  61. new_menu_item(pulldown, DIALOG_ABOUT);
  62. return menubar;
  63. }
  64. static Widget
  65. CreateRowCol(const char *name, Widget parent) {
  66. return XtVaCreateManagedWidget(name, xmRowColumnWidgetClass, parent,
  67. XmNorientation, XmVERTICAL, NULL);
  68. }
  69. static void
  70. CreatePixmapBox(int index, Widget parent, Pixmap logo, Pixmap pixmap) {
  71. Arg wargs[2];
  72. XmString mstr;
  73. Widget dialog, base;
  74. const char *text = UI_dialog_string(index);
  75. mstr = XmStringCreateLtoR("", XmSTRING_DEFAULT_CHARSET);
  76. XtSetArg(wargs[0], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);
  77. XtSetArg(wargs[1], XmNmessageString, mstr);
  78. dialog = XmCreateMessageDialog(parent, (char *)UI_menu_string(index),
  79. wargs, 2);
  80. base = CreateRowCol("", dialog);
  81. XtVaCreateManagedWidget("", xmLabelWidgetClass, base, XmNlabelType,
  82. XmPIXMAP, XmNlabelPixmap, logo, NULL);
  83. if (pixmap)
  84. XtVaCreateManagedWidget("", xmLabelWidgetClass, base,
  85. XmNlabelType, XmPIXMAP,
  86. XmNlabelPixmap, pixmap, NULL);
  87. if (text) {
  88. mstr = XmStringCreateLtoR((char *)text,
  89. XmSTRING_DEFAULT_CHARSET);
  90. XtVaCreateManagedWidget(text, xmLabelWidgetClass, base,
  91. XmNlabelString, mstr, NULL);
  92. XmStringFree(mstr);
  93. }
  94. XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON));
  95. XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  96. dialogs[index] = dialog;
  97. }
  98. static void
  99. CreateEnterText(int index, Widget parent, XtCallbackProc callback) {
  100. Widget dialog;
  101. Arg wargs[2];
  102. XmString mstr = XmStringCreateLtoR((char *) UI_dialog_string(index),
  103. XmSTRING_DEFAULT_CHARSET);
  104. XtSetArg(wargs[0], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);
  105. XtSetArg(wargs[1], XmNselectionLabelString, mstr);
  106. dialog = XmCreatePromptDialog(parent, (char *) UI_menu_string(index),
  107. wargs, 2);
  108. XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  109. XtUnmanageChild(XmSelectionBoxGetChild(dialog, XmDIALOG_APPLY_BUTTON));
  110. XtAddCallback(dialog, XmNokCallback, callback,
  111. XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT));
  112. dialogs[index] = dialog;
  113. }
  114. static void
  115. CreateDialog(int index, Widget parent, int hascancel, Pixmap icon,
  116. const char *buttonlabel, XtCallbackProc callback)
  117. {
  118. Widget dialog;
  119. Arg wargs[2];
  120. XmString mstr = XmStringCreateLtoR((char *) UI_dialog_string(index),
  121. XmSTRING_DEFAULT_CHARSET);
  122. XtSetArg(wargs[0], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL);
  123. XtSetArg(wargs[1], XmNmessageString, mstr);
  124. dialog = XmCreateMessageDialog(parent, (char *) UI_menu_string(index),
  125. wargs, 2);
  126. if (icon != (Pixmap) NULL)
  127. XtVaSetValues(dialog, XmNsymbolPixmap, icon, NULL);
  128. XmStringFree(mstr);
  129. if (!hascancel)
  130. XtUnmanageChild(XmMessageBoxGetChild(dialog,
  131. XmDIALOG_CANCEL_BUTTON));
  132. XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON));
  133. if (buttonlabel != NULL) {
  134. mstr = XmStringCreateLtoR((char *) buttonlabel,
  135. XmSTRING_DEFAULT_CHARSET);
  136. XtVaSetValues(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON),
  137. XmNlabelString, mstr, NULL);
  138. XmStringFree(mstr);
  139. }
  140. if (callback != NULL)
  141. XtAddCallback(dialog, XmNokCallback, callback, NULL);
  142. dialogs[index] = dialog;
  143. }
  144. static Widget
  145. CreateDrawingArea(const char *name, Widget parent, int width, int height) {
  146. return XtVaCreateManagedWidget(name, xmDrawingAreaWidgetClass, parent,
  147. XtNwidth, width, XtNheight, height,
  148. XmNresizePolicy, FALSE, NULL);
  149. }
  150. static void
  151. x11_motif_update_dialog(int index, const char *str) {
  152. XmString mstr = XmStringCreateLtoR((char *) str,
  153. XmSTRING_DEFAULT_CHARSET);
  154. XtVaSetValues(
  155. XmMessageBoxGetChild(dialogs[index], XmDIALOG_MESSAGE_LABEL),
  156. XmNlabelString, mstr, NULL);
  157. XmStringFree(mstr);
  158. }
  159. static void
  160. x11_motif_make_main_window(int size) {
  161. x11_setup_resources();
  162. base = CreateRowCol("base", x11_toplevel());
  163. menubar = CreateMenuBar("menubar", base);
  164. field = CreateDrawingArea("field", base, size, size);
  165. x11_setup();
  166. x11_set_drawingarea(field, size);
  167. x11_add_event_handlers(field);
  168. }
  169. static void
  170. new_game(Widget w, XtPointer client_data, XtPointer call_data) {
  171. UNUSED(w);
  172. UNUSED(client_data);
  173. UNUSED(call_data);
  174. Game_start(1);
  175. }
  176. static void
  177. quit_game(Widget w, XtPointer client_data, XtPointer call_data) {
  178. UNUSED(w);
  179. UNUSED(client_data);
  180. UNUSED(call_data);
  181. Game_quit();
  182. }
  183. static void
  184. warp_apply(Widget w, XtPointer client_data, XtPointer call_data) {
  185. char *str;
  186. char *endp;
  187. int newlevel;
  188. Widget text = (Widget) client_data;
  189. UNUSED(w);
  190. UNUSED(call_data);
  191. str = XmTextGetString(text);
  192. newlevel = strtol(str, &endp, 10);
  193. if (*endp != '\0')
  194. return;
  195. XtFree(str);
  196. Game_warp_to_level(newlevel);
  197. }
  198. static void
  199. enter_name(Widget w, XtPointer client_data, XtPointer call_data) {
  200. char *str;
  201. Widget text = (Widget) client_data;
  202. UNUSED(w);
  203. UNUSED(call_data);
  204. str = XmTextGetString(text);
  205. Game_add_high_score(str);
  206. XtFree(str);
  207. }
  208. static void
  209. x11_motif_create_dialogs(Picture *logo, Picture *icon, Picture *about) {
  210. CreateDialog(DIALOG_NEWGAME, base, 1, (Pixmap)NULL, NULL, new_game);
  211. CreateDialog(DIALOG_PAUSEGAME, base, 0, icon->pix, "Continue", NULL);
  212. CreateEnterText(DIALOG_WARPLEVEL, base, warp_apply);
  213. CreateDialog(DIALOG_HIGHSCORE, base, 0, (Pixmap)NULL, NULL, NULL);
  214. CreateDialog(DIALOG_QUITGAME, base, 1, (Pixmap)NULL, NULL, quit_game);
  215. CreatePixmapBox(DIALOG_STORY, base, logo->pix, (Pixmap)NULL);
  216. CreatePixmapBox(DIALOG_RULES, base, logo->pix, (Pixmap)NULL);
  217. CreatePixmapBox(DIALOG_ABOUT, base, logo->pix, about->pix);
  218. CreateDialog(DIALOG_SCORE, base, 0, (Pixmap)NULL, NULL, NULL);
  219. CreateDialog(DIALOG_ENDGAME, base, 0, (Pixmap)NULL, "Nuts!", NULL);
  220. CreateEnterText(DIALOG_ENTERNAME, base, enter_name);
  221. }
  222. static void
  223. x11_motif_set_pausebutton(int active) {
  224. if (pausebutton != NULL)
  225. XtSetSensitive(pausebutton, active);
  226. }
  227. static struct UI_methods x11_motif_methods = {
  228. x11_set_cursor,
  229. x11_load_cursor,
  230. x11_load_picture,
  231. x11_set_icon,
  232. x11_picture_width,
  233. x11_picture_height,
  234. x11_graphics_init,
  235. x11_clear_window,
  236. x11_refresh_window,
  237. x11_draw_image,
  238. x11_draw_line,
  239. x11_draw_string,
  240. x11_start_timer,
  241. x11_stop_timer,
  242. x11_timer_active,
  243. x11_motif_popup_dialog,
  244. x11_main_loop,
  245. x11_initialize,
  246. x11_motif_make_main_window,
  247. x11_motif_create_dialogs,
  248. x11_motif_set_pausebutton,
  249. x11_motif_update_dialog,
  250. };
  251. void
  252. x11_motif_setmethods(UI_methods **methodsp) {
  253. *methodsp = &x11_motif_methods;
  254. }