1 /*
2 * xcpc_athena.c - Copyright (c) 2001, 2006, 2007 Olivier Poncet
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <X11/Intrinsic.h>
25 #include <Xem/StringDefs.h>
26 #include <Xem/AppShell.h>
27 #include <Xem/DlgShell.h>
28 #include <Xem/Emulator.h>
29 #include "amstrad_cpc.h"
30 #include "xcpc.h"
31
32 static Widget CreateGUI(Widget toplevel);
33
34 /*
35 * command line options
36 */
37 static XrmOptionDescRec options[] = {
38 { "-version", ".xcpcAboutFlag", XrmoptionNoArg, (XPointer) "true" },
39 { "-help", ".xcpcUsageFlag", XrmoptionNoArg, (XPointer) "true" },
40 { "-editres", ".xcpcEdresFlag", XrmoptionNoArg, (XPointer) "true" }
41 };
42
43 /*
44 * fallback resources
45 */
46 static String fallback_resources[] = {
47 "*title: Xcpc - Amstrad CPC emulator",
48 NULL
49 };
50
51 /*
52 * application resources
53 */
54 static XtResource application_resources[] = {
55 /* xcpcAboutFlag */ {
56 "xcpcAboutFlag", "XcpcAboutFlag", XtRBoolean,
57 sizeof(Boolean), XtOffsetOf(XcpcResourcesRec, about_flag),
58 XtRImmediate, (XtPointer) FALSE
59 },
60 /* xcpcUsageFlag */ {
61 "xcpcUsageFlag", "XcpcUsageFlag", XtRBoolean,
62 sizeof(Boolean), XtOffsetOf(XcpcResourcesRec, usage_flag),
63 XtRImmediate, (XtPointer) FALSE
64 },
65 /* xcpcEdresFlag */ {
66 "xcpcEdresFlag", "XcpcEdresFlag", XtRBoolean,
67 sizeof(Boolean), XtOffsetOf(XcpcResourcesRec, edres_flag),
68 XtRImmediate, (XtPointer) FALSE
69 }
70 };
71
72 /*
73 * Xcpc resources
74 */
75 static XcpcResourcesRec xcpc_resources = {
76 FALSE, /* about_flag */
77 FALSE, /* usage_flag */
78 FALSE /* edres_flag */
79 };
80
81 /**
82 * Destroy Callback
83 *
84 * @param widget specifies the Widget instance
85 * @param widref specifies the Widget reference
86 * @param cbdata is not used
87 */
DestroyCbk(Widget widget,Widget * widref,XtPointer cbdata)88 static void DestroyCbk(Widget widget, Widget *widref, XtPointer cbdata)
89 {
90 if(XtIsApplicationShell(widget) != FALSE) {
91 XtAppSetExitFlag(XtWidgetToApplicationContext(widget));
92 }
93 if((widget != NULL) && (widref != NULL) && (widget == *widref)) {
94 *widref = NULL;
95 }
96 }
97
98 /**
99 * main
100 *
101 * @param argc specifies the argument count
102 * @param argv specifies the argument list
103 *
104 * @return EXIT_SUCCESS or EXIT_FAILURE
105 */
main(int argc,char * argv[])106 int main(int argc, char *argv[])
107 {
108 XtAppContext appcontext;
109 String appname = NULL;
110 String appclass = NULL;
111 Widget toplevel = NULL;
112 Widget apwindow = NULL;
113 Cardinal argcount = 0;
114 Arg arglist[4];
115
116 (void) XtSetLanguageProc(NULL, NULL, NULL);
117 argcount = 0;
118 XtSetArg(arglist[argcount], XtNmappedWhenManaged, TRUE); argcount++;
119 XtSetArg(arglist[argcount], XtNallowShellResize, TRUE); argcount++;
120 toplevel = XtOpenApplication(&appcontext, "Xcpc", options, XtNumber(options), &argc, argv, fallback_resources, xemAppShellWidgetClass, arglist, argcount);
121 XtAddCallback(toplevel, XtNdestroyCallback, (XtCallbackProc) DestroyCbk, (XtPointer) &toplevel);
122 argcount = 0;
123 XtGetApplicationResources(toplevel, (XtPointer) &xcpc_resources, application_resources, XtNumber(application_resources), arglist, argcount);
124 XtGetApplicationNameAndClass(XtDisplay(toplevel), &appname, &appclass);
125 if(xcpc_resources.about_flag != FALSE) {
126 (void) fprintf(stdout, "%s %s\n", appname, PACKAGE_VERSION);
127 (void) fflush(stdout);
128 exit(EXIT_SUCCESS);
129 }
130 if((xcpc_resources.usage_flag != FALSE) || (amstrad_cpc_parse(&argc, &argv) == EXIT_FAILURE)) {
131 (void) fprintf(stdout, "Usage: %s [toolkit-options] [program-options]\n\n", appname);
132 (void) fprintf(stdout, "Options:\n");
133 (void) fprintf(stdout, " -version print version and exit.\n");
134 (void) fprintf(stdout, " -help display this help and exit.\n");
135 (void) fflush(stdout);
136 exit(EXIT_SUCCESS);
137 }
138 if(xcpc_resources.edres_flag != FALSE) {
139 XtAddEventHandler(toplevel, NoEventMask, TRUE, (XtEventHandler) _XEditResCheckMessages, (XtPointer) NULL);
140 }
141 /* XXX */ {
142 g_type_init(); apwindow = CreateGUI(toplevel);
143 }
144 XtManageChild(apwindow);
145 XtRealizeWidget(toplevel);
146 XtAppMainLoop(appcontext);
147 if(toplevel != NULL) {
148 XtDestroyWidget(toplevel);
149 }
150 XtDestroyApplicationContext(appcontext);
151 return(EXIT_SUCCESS);
152 }
153
154 /*
155 * GUI instance structure
156 */
157 typedef struct _GUI {
158 Widget main_wnd;
159 Widget menu_bar;
160 Widget file_menu;
161 Widget file_pldn;
162 Widget load_snapshot;
163 Widget save_snapshot;
164 Widget separator1;
165 Widget drivea_insert;
166 Widget drivea_eject;
167 Widget separator2;
168 Widget driveb_insert;
169 Widget driveb_eject;
170 Widget separator3;
171 Widget exit_emulator;
172 Widget ctrl_menu;
173 Widget ctrl_pldn;
174 Widget pause_emu;
175 Widget reset_emu;
176 Widget help_menu;
177 Widget help_pldn;
178 Widget legal_info;
179 Widget separator4;
180 Widget about_xcpc;
181 Widget emulator;
182 } GUI;
183
184 #include <X11/Xaw/Box.h>
185 #include <X11/Xaw/MenuButton.h>
186 #include <X11/Xaw/SimpleMenu.h>
187 #include <X11/Xaw/SmeBSB.h>
188 #include <X11/Xaw/SmeLine.h>
189 #include <X11/Xaw/Dialog.h>
190
191 /**
192 * GUI::OnCloseCbk()
193 *
194 * @param widget specifies the Widget
195 * @param gui specifies the GUI
196 * @param cbs specifies the callback info
197 */
OnCloseCbk(Widget widget,GUI * gui,XtPointer cbs)198 static void OnCloseCbk(Widget widget, GUI *gui, XtPointer cbs)
199 {
200 while((widget != NULL) && (XtIsShell(widget) == FALSE)) {
201 widget = XtParent(widget);
202 }
203 XtPopdown(widget);
204 XtDestroyWidget(widget);
205 XtSetSensitive(gui->emulator, TRUE);
206 }
207
208 /**
209 * GUI::OnLoadSnapshotOkCbk()
210 *
211 * @param widget specifies the Widget
212 * @param gui specifies the GUI
213 * @param cbs specifies the callback info
214 */
OnLoadSnapshotOkCbk(Widget widget,GUI * gui,XtPointer cbs)215 static void OnLoadSnapshotOkCbk(Widget widget, GUI *gui, XtPointer cbs)
216 {
217 char *value = XawDialogGetValueString(XtParent(widget));
218 if(value != NULL) {
219 amstrad_cpc_load_snapshot(value);
220 }
221 OnCloseCbk(widget, gui, cbs);
222 }
223
224 /**
225 * GUI::OnLoadSnapshotCbk()
226 *
227 * @param widget specifies the Widget
228 * @param gui specifies the GUI
229 * @param cbs specifies the callback info
230 */
OnLoadSnapshotCbk(Widget widget,GUI * gui,XtPointer cbs)231 static void OnLoadSnapshotCbk(Widget widget, GUI *gui, XtPointer cbs)
232 {
233 Widget shell, dialog, btn_ok, cancel;
234 Arg arglist[8];
235 Cardinal argcount;
236
237 XtSetSensitive(gui->emulator, FALSE);
238 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
239 widget = XtParent(widget);
240 }
241 /* load-snapshot-shell */
242 argcount = 0;
243 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
244 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
245 shell = XtCreatePopupShell("load-snapshot-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
246 /* load-snapshot-dialog */
247 argcount = 0;
248 XtSetArg(arglist[argcount], XtNlabel, _("Load a snapshot ...")); argcount++;
249 XtSetArg(arglist[argcount], XtNvalue, ""); argcount++;
250 dialog = XtCreateWidget("load-snapshot-dialog", dialogWidgetClass, shell, arglist, argcount);
251 XtManageChild(dialog);
252 /* load-snapshot-btn-ok */
253 argcount = 0;
254 XtSetArg(arglist[argcount], XtNlabel, _(" Load ")); argcount++;
255 btn_ok = XtCreateManagedWidget("load-snapshot-btn-ok", commandWidgetClass, dialog, arglist, argcount);
256 XtAddCallback(btn_ok, XtNcallback, (XtCallbackProc) OnLoadSnapshotOkCbk, (XtPointer) gui);
257 XtManageChild(btn_ok);
258 /* load-snapshot-cancel */
259 argcount = 0;
260 XtSetArg(arglist[argcount], XtNlabel, _("Cancel")); argcount++;
261 cancel = XtCreateManagedWidget("load-snapshot-cancel", commandWidgetClass, dialog, arglist, argcount);
262 XtAddCallback(cancel, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
263 XtManageChild(cancel);
264 /* load-snapshot-popup */
265 XtPopup(shell, XtGrabExclusive);
266 }
267
268 /**
269 * GUI::OnSaveSnapshotOkCbk()
270 *
271 * @param widget specifies the Widget
272 * @param gui specifies the GUI
273 * @param cbs specifies the callback info
274 */
OnSaveSnapshotOkCbk(Widget widget,GUI * gui,XtPointer cbs)275 static void OnSaveSnapshotOkCbk(Widget widget, GUI *gui, XtPointer cbs)
276 {
277 char *value = XawDialogGetValueString(XtParent(widget));
278 if(value != NULL) {
279 amstrad_cpc_save_snapshot(value);
280 }
281 OnCloseCbk(widget, gui, cbs);
282 }
283
284 /**
285 * GUI::OnSaveSnapshotCbk()
286 *
287 * @param widget specifies the Widget
288 * @param gui specifies the GUI
289 * @param cbs specifies the callback info
290 */
OnSaveSnapshotCbk(Widget widget,GUI * gui,XtPointer cbs)291 static void OnSaveSnapshotCbk(Widget widget, GUI *gui, XtPointer cbs)
292 {
293 Widget shell, dialog, btn_ok, cancel;
294 Arg arglist[8];
295 Cardinal argcount;
296
297 XtSetSensitive(gui->emulator, FALSE);
298 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
299 widget = XtParent(widget);
300 }
301 /* save-snapshot-shell */
302 argcount = 0;
303 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
304 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
305 shell = XtCreatePopupShell("save-snapshot-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
306 /* save-snapshot-dialog */
307 argcount = 0;
308 XtSetArg(arglist[argcount], XtNlabel, _("Save a snapshot ...")); argcount++;
309 XtSetArg(arglist[argcount], XtNvalue, ""); argcount++;
310 dialog = XtCreateWidget("save-snapshot-dialog", dialogWidgetClass, shell, arglist, argcount);
311 XtManageChild(dialog);
312 /* save-snapshot-btn-ok */
313 argcount = 0;
314 XtSetArg(arglist[argcount], XtNlabel, _(" Save ")); argcount++;
315 btn_ok = XtCreateManagedWidget("save-snapshot-btn-ok", commandWidgetClass, dialog, arglist, argcount);
316 XtAddCallback(btn_ok, XtNcallback, (XtCallbackProc) OnSaveSnapshotOkCbk, (XtPointer) gui);
317 XtManageChild(btn_ok);
318 /* save-snapshot-cancel */
319 argcount = 0;
320 XtSetArg(arglist[argcount], XtNlabel, _("Cancel")); argcount++;
321 cancel = XtCreateManagedWidget("save-snapshot-cancel", commandWidgetClass, dialog, arglist, argcount);
322 XtAddCallback(cancel, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
323 XtManageChild(cancel);
324 /* save-snapshot-popup */
325 XtPopup(shell, XtGrabExclusive);
326 }
327
328 /**
329 * GUI::OnDriveAInsertOkCbk()
330 *
331 * @param widget specifies the Widget
332 * @param gui specifies the GUI
333 * @param cbs specifies the callback info
334 */
OnDriveAInsertOkCbk(Widget widget,GUI * gui,XtPointer cbs)335 static void OnDriveAInsertOkCbk(Widget widget, GUI *gui, XtPointer cbs)
336 {
337 char *value = XawDialogGetValueString(XtParent(widget));
338 if(value != NULL) {
339 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[0], value);
340 }
341 OnCloseCbk(widget, gui, cbs);
342 }
343
344 /**
345 * GUI::OnDriveAInsertCbk()
346 *
347 * @param widget specifies the Widget
348 * @param gui specifies the GUI
349 * @param cbs specifies the callback info
350 */
OnDriveAInsertCbk(Widget widget,GUI * gui,XtPointer cbs)351 static void OnDriveAInsertCbk(Widget widget, GUI *gui, XtPointer cbs)
352 {
353 Widget shell, dialog, btn_ok, cancel;
354 Arg arglist[8];
355 Cardinal argcount;
356
357 XtSetSensitive(gui->emulator, FALSE);
358 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
359 widget = XtParent(widget);
360 }
361 /* drivea-insert-shell */
362 argcount = 0;
363 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
364 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
365 shell = XtCreatePopupShell("drivea-insert-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
366 /* drivea-insert-dialog */
367 argcount = 0;
368 XtSetArg(arglist[argcount], XtNlabel, _("Insert disk into drive A ...")); argcount++;
369 XtSetArg(arglist[argcount], XtNvalue, ""); argcount++;
370 dialog = XtCreateWidget("drivea-insert-dialog", dialogWidgetClass, shell, arglist, argcount);
371 XtManageChild(dialog);
372 /* drivea-insert-btn-ok */
373 argcount = 0;
374 XtSetArg(arglist[argcount], XtNlabel, _("Insert")); argcount++;
375 btn_ok = XtCreateManagedWidget("drivea-insert-btn-ok", commandWidgetClass, dialog, arglist, argcount);
376 XtAddCallback(btn_ok, XtNcallback, (XtCallbackProc) OnDriveAInsertOkCbk, (XtPointer) gui);
377 XtManageChild(btn_ok);
378 /* drivea-insert-cancel */
379 argcount = 0;
380 XtSetArg(arglist[argcount], XtNlabel, _("Cancel")); argcount++;
381 cancel = XtCreateManagedWidget("drivea-insert-cancel", commandWidgetClass, dialog, arglist, argcount);
382 XtAddCallback(cancel, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
383 XtManageChild(cancel);
384 /* drivea-insert-popup */
385 XtPopup(shell, XtGrabExclusive);
386 }
387
388 /**
389 * GUI::OnDriveAEjectCbk()
390 *
391 * @param widget specifies the Widget
392 * @param gui specifies the GUI
393 * @param cbs specifies the callback info
394 */
OnDriveAEjectCbk(Widget widget,GUI * gui,XtPointer cbs)395 static void OnDriveAEjectCbk(Widget widget, GUI *gui, XtPointer cbs)
396 {
397 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[0], NULL);
398 }
399
400 /**
401 * GUI::OnDriveBInsertOkCbk()
402 *
403 * @param widget specifies the Widget
404 * @param gui specifies the GUI
405 * @param cbs specifies the callback info
406 */
OnDriveBInsertOkCbk(Widget widget,GUI * gui,XtPointer cbs)407 static void OnDriveBInsertOkCbk(Widget widget, GUI *gui, XtPointer cbs)
408 {
409 char *value = XawDialogGetValueString(XtParent(widget));
410 if(value != NULL) {
411 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[1], value);
412 }
413 OnCloseCbk(widget, gui, cbs);
414 }
415
416 /**
417 * GUI::OnDriveBInsertCbk()
418 *
419 * @param widget specifies the Widget
420 * @param gui specifies the GUI
421 * @param cbs specifies the callback info
422 */
OnDriveBInsertCbk(Widget widget,GUI * gui,XtPointer cbs)423 static void OnDriveBInsertCbk(Widget widget, GUI *gui, XtPointer cbs)
424 {
425 Widget shell, dialog, btn_ok, cancel;
426 Arg arglist[8];
427 Cardinal argcount;
428
429 XtSetSensitive(gui->emulator, FALSE);
430 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
431 widget = XtParent(widget);
432 }
433 /* driveb-insert-shell */
434 argcount = 0;
435 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
436 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
437 shell = XtCreatePopupShell("driveb-insert-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
438 /* driveb-insert-dialog */
439 argcount = 0;
440 XtSetArg(arglist[argcount], XtNlabel, _("Insert disk into drive B ...")); argcount++;
441 XtSetArg(arglist[argcount], XtNvalue, ""); argcount++;
442 dialog = XtCreateWidget("driveb-insert-dialog", dialogWidgetClass, shell, arglist, argcount);
443 XtManageChild(dialog);
444 /* driveb-insert-btn-ok */
445 argcount = 0;
446 XtSetArg(arglist[argcount], XtNlabel, _("Insert")); argcount++;
447 btn_ok = XtCreateManagedWidget("driveb-insert-btn-ok", commandWidgetClass, dialog, arglist, argcount);
448 XtAddCallback(btn_ok, XtNcallback, (XtCallbackProc) OnDriveBInsertOkCbk, (XtPointer) gui);
449 XtManageChild(btn_ok);
450 /* driveb-insert-cancel */
451 argcount = 0;
452 XtSetArg(arglist[argcount], XtNlabel, _("Cancel")); argcount++;
453 cancel = XtCreateManagedWidget("driveb-insert-cancel", commandWidgetClass, dialog, arglist, argcount);
454 XtAddCallback(cancel, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
455 XtManageChild(cancel);
456 /* driveb-insert-popup */
457 XtPopup(shell, XtGrabExclusive);
458 }
459
460 /**
461 * GUI::OnDriveBEjectCbk()
462 *
463 * @param widget specifies the Widget
464 * @param gui specifies the GUI
465 * @param cbs specifies the callback info
466 */
OnDriveBEjectCbk(Widget widget,GUI * gui,XtPointer cbs)467 static void OnDriveBEjectCbk(Widget widget, GUI *gui, XtPointer cbs)
468 {
469 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[1], NULL);
470 }
471
472 /**
473 * GUI::OnExitEmulatorCbk()
474 *
475 * @param widget specifies the Widget
476 * @param gui specifies the GUI
477 * @param cbs specifies the callback info
478 */
OnExitEmulatorCbk(Widget widget,GUI * gui,XtPointer cbs)479 static void OnExitEmulatorCbk(Widget widget, GUI *gui, XtPointer cbs)
480 {
481 XtAppSetExitFlag(XtWidgetToApplicationContext(widget));
482 }
483
484 /**
485 * GUI::OnPauseCbk()
486 *
487 * @param widget specifies the Widget
488 * @param gui specifies the GUI
489 * @param cbs specifies the callback info
490 */
OnPauseCbk(Widget widget,GUI * gui,XtPointer cbs)491 static void OnPauseCbk(Widget widget, GUI *gui, XtPointer cbs)
492 {
493 if(XtIsSensitive(gui->emulator) != FALSE) {
494 XtSetSensitive(gui->emulator, FALSE);
495 }
496 else {
497 XtSetSensitive(gui->emulator, TRUE);
498 }
499 }
500
501 /**
502 * GUI::OnResetCbk()
503 *
504 * @param widget specifies the Widget
505 * @param gui specifies the GUI
506 * @param cbs specifies the callback info
507 */
OnResetCbk(Widget widget,GUI * gui,XtPointer cbs)508 static void OnResetCbk(Widget widget, GUI *gui, XtPointer cbs)
509 {
510 amstrad_cpc_reset();
511 XtSetSensitive(gui->emulator, TRUE);
512 }
513
514 /**
515 * GUI::OnLegalInfoCbk()
516 *
517 * @param widget specifies the Widget
518 * @param gui specifies the GUI
519 * @param cbs specifies the callback info
520 */
OnLegalInfoCbk(Widget widget,GUI * gui,XtPointer cbs)521 static void OnLegalInfoCbk(Widget widget, GUI *gui, XtPointer cbs)
522 {
523 Widget shell, dialog, button;
524 Arg arglist[8];
525 Cardinal argcount;
526 String message = _(
527 "Amstrad has kindly given it's permission for it's copyrighted\n"
528 "material to be redistributed but Amstrad retains it's copyright.\n\n"
529 "Some of the Amstrad CPC ROM code is copyright Locomotive Software.\n\n"
530 "ROM and DISK images are protected under the copyrights of their authors,\n"
531 "and cannot be distributed in this package. You can download and/or use\n"
532 "ROM and DISK images at your own risk and responsibility."
533 );
534
535 XtSetSensitive(gui->emulator, FALSE);
536 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
537 widget = XtParent(widget);
538 }
539 /* legal-info-shell */
540 argcount = 0;
541 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
542 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
543 shell = XtCreatePopupShell("legal-info-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
544 /* legal-info-dialog */
545 argcount = 0;
546 XtSetArg(arglist[argcount], XtNlabel, message); argcount++;
547 dialog = XtCreateWidget("legal-info-dialog", dialogWidgetClass, shell, arglist, argcount);
548 XtManageChild(dialog);
549 /* legal-info-btn-ok */
550 argcount = 0;
551 XtSetArg(arglist[argcount], XtNlabel, _("OK")); argcount++;
552 button = XtCreateManagedWidget("legal-info-btn-ok", commandWidgetClass, dialog, arglist, argcount);
553 XtAddCallback(button, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
554 XtManageChild(button);
555 /* legal-info-popup */
556 XtPopup(shell, XtGrabExclusive);
557 }
558
559 /**
560 * GUI::OnAboutXcpcCbk()
561 *
562 * @param widget specifies the Widget
563 * @param gui specifies the GUI
564 * @param cbs specifies the callback info
565 */
OnAboutXcpcCbk(Widget widget,GUI * gui,XtPointer cbs)566 static void OnAboutXcpcCbk(Widget widget, GUI *gui, XtPointer cbs)
567 {
568 Widget shell, dialog, button;
569 Arg arglist[8];
570 Cardinal argcount;
571 String message = _(
572 PACKAGE_STRING " - Amstrad CPC Emulator - Copyright (c) 2001, 2006, 2007 Olivier Poncet\n\n"
573 "This program is free software; you can redistribute it and/or modify\n"
574 "it under the terms of the GNU General Public License as published by\n"
575 "the Free Software Foundation; either version 2 of the License, or\n"
576 "(at your option) any later version.\n\n"
577 "This program is distributed in the hope that it will be useful,\n"
578 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
579 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
580 "GNU General Public License for more details.\n\n"
581 "You should have received a copy of the GNU General Public License\n"
582 "along with this program; if not, write to the Free Software\n"
583 "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA"
584 );
585
586 XtSetSensitive(gui->emulator, FALSE);
587 while((widget != NULL) && (XtIsTopLevelShell(widget) == FALSE)) {
588 widget = XtParent(widget);
589 }
590 /* about-xcpc-shell */
591 argcount = 0;
592 XtSetArg(arglist[argcount], XtNtransient, TRUE); argcount++;
593 XtSetArg(arglist[argcount], XtNtransientFor, widget); argcount++;
594 shell = XtCreatePopupShell("about-xcpc-shell", xemDlgShellWidgetClass, widget, arglist, argcount);
595 /* about-xcpc-dialog */
596 argcount = 0;
597 XtSetArg(arglist[argcount], XtNlabel, message); argcount++;
598 dialog = XtCreateWidget("about-xcpc-dialog", dialogWidgetClass, shell, arglist, argcount);
599 XtManageChild(dialog);
600 /* about-xcpc-btn-ok */
601 argcount = 0;
602 XtSetArg(arglist[argcount], XtNlabel, _("OK")); argcount++;
603 button = XtCreateManagedWidget("about-xcpc-btn-ok", commandWidgetClass, dialog, arglist, argcount);
604 XtAddCallback(button, XtNcallback, (XtCallbackProc) OnCloseCbk, (XtPointer) gui);
605 XtManageChild(button);
606 /* about-xcpc-popup */
607 XtPopup(shell, XtGrabExclusive);
608 }
609
610 /**
611 * GUI::OnDropURICbk()
612 *
613 * @param widget specifies the Widget
614 * @param gui specifies the GUI
615 * @param uri specifies the callback info
616 */
OnDropURICbk(Widget widget,GUI * gui,char * uri)617 static void OnDropURICbk(Widget widget, GUI *gui, char *uri)
618 {
619 int length = 0;
620
621 if((uri != NULL) && (strncmp(uri, "file://", 7) == 0)) {
622 char *str = &uri[7], *ptr = strstr(str, "\r\n");
623 if(ptr != NULL) {
624 *ptr = '\0';
625 }
626 if((length = strlen(str)) >= 4) {
627 if(strcmp(&str[length - 4], ".sna") == 0) {
628 amstrad_cpc_load_snapshot(str);
629 }
630 if(strcmp(&str[length - 4], ".dsk") == 0) {
631 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[0], str);
632 gdev_fdd765_insert(amstrad_cpc.upd765->fdd[1], str);
633 }
634 XtSetSensitive(gui->emulator, TRUE);
635 XtSetSensitive(gui->emulator, TRUE);
636 }
637 }
638 }
639
640 /**
641 * GUI::Create()
642 *
643 * @param toplevel specifies the TopLevel Shell
644 *
645 * @return the main-window instance
646 */
CreateGUI(Widget toplevel)647 static Widget CreateGUI(Widget toplevel)
648 {
649 GUI *gui = (GUI *) XtMalloc(sizeof(GUI));
650 Arg arglist[8];
651 Cardinal argcount;
652
653 /* main-wnd */
654 argcount = 0;
655 gui->main_wnd = XtCreateWidget("main-wnd", boxWidgetClass, toplevel, arglist, argcount);
656 /* menu-bar */
657 argcount = 0;
658 XtSetArg(arglist[argcount], XtNorientation, XtorientHorizontal); argcount++;
659 XtSetArg(arglist[argcount], XtNborderWidth, 0); argcount++;
660 gui->menu_bar = XtCreateWidget("menu-bar", boxWidgetClass, gui->main_wnd, arglist, argcount);
661 XtManageChild(gui->menu_bar);
662 /* file-menu */
663 argcount = 0;
664 XtSetArg(arglist[argcount], XtNlabel, _("File")); argcount++;
665 XtSetArg(arglist[argcount], XtNmenuName, "file-pldn"); argcount++;
666 gui->file_menu = XtCreateWidget("file-menu", menuButtonWidgetClass, gui->menu_bar, arglist, argcount);
667 XtManageChild(gui->file_menu);
668 /* file-pldn */
669 argcount = 0;
670 gui->file_pldn = XtCreatePopupShell("file-pldn", simpleMenuWidgetClass, gui->file_menu, arglist, argcount);
671 /* load-snapshot */
672 argcount = 0;
673 XtSetArg(arglist[argcount], XtNlabel, _("Load Snapshot")); argcount++;
674 gui->load_snapshot = XtCreateWidget("load-snapshot", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
675 XtAddCallback(gui->load_snapshot, XtNcallback, (XtCallbackProc) OnLoadSnapshotCbk, (XtPointer) gui);
676 XtManageChild(gui->load_snapshot);
677 /* save-snapshot */
678 argcount = 0;
679 XtSetArg(arglist[argcount], XtNlabel, _("Save Snapshot")); argcount++;
680 gui->save_snapshot = XtCreateWidget("save-snapshot", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
681 XtAddCallback(gui->save_snapshot, XtNcallback, (XtCallbackProc) OnSaveSnapshotCbk, (XtPointer) gui);
682 XtManageChild(gui->save_snapshot);
683 /* separator1 */
684 argcount = 0;
685 gui->separator1 = XtCreateWidget("separator1", smeLineObjectClass, gui->file_pldn, arglist, argcount);
686 XtManageChild(gui->separator1);
687 /* drivea-insert */
688 argcount = 0;
689 XtSetArg(arglist[argcount], XtNlabel, _("Insert disk into drive A")); argcount++;
690 gui->drivea_insert = XtCreateWidget("drivea-insert", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
691 XtAddCallback(gui->drivea_insert, XtNcallback, (XtCallbackProc) OnDriveAInsertCbk, (XtPointer) gui);
692 XtManageChild(gui->drivea_insert);
693 /* drivea-eject */
694 argcount = 0;
695 XtSetArg(arglist[argcount], XtNlabel, _("Eject disk from drive A")); argcount++;
696 gui->drivea_eject = XtCreateWidget("drivea-eject", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
697 XtAddCallback(gui->drivea_eject, XtNcallback, (XtCallbackProc) OnDriveAEjectCbk, (XtPointer) gui);
698 XtManageChild(gui->drivea_eject);
699 /* separator2 */
700 argcount = 0;
701 gui->separator2 = XtCreateWidget("separator2", smeLineObjectClass, gui->file_pldn, arglist, argcount);
702 XtManageChild(gui->separator2);
703 /* driveb-insert */
704 argcount = 0;
705 XtSetArg(arglist[argcount], XtNlabel, _("Insert disk into drive B")); argcount++;
706 gui->driveb_insert = XtCreateWidget("driveb-insert", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
707 XtAddCallback(gui->driveb_insert, XtNcallback, (XtCallbackProc) OnDriveBInsertCbk, (XtPointer) gui);
708 XtManageChild(gui->driveb_insert);
709 /* driveb-eject */
710 argcount = 0;
711 XtSetArg(arglist[argcount], XtNlabel, _("Eject disk from drive B")); argcount++;
712 gui->driveb_eject = XtCreateWidget("driveb-eject", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
713 XtAddCallback(gui->driveb_eject, XtNcallback, (XtCallbackProc) OnDriveBEjectCbk, (XtPointer) gui);
714 XtManageChild(gui->driveb_eject);
715 /* separator3 */
716 argcount = 0;
717 gui->separator3 = XtCreateWidget("separator3", smeLineObjectClass, gui->file_pldn, arglist, argcount);
718 XtManageChild(gui->separator3);
719 /* exit-emulator */
720 argcount = 0;
721 XtSetArg(arglist[argcount], XtNlabel, _("Exit")); argcount++;
722 gui->exit_emulator = XtCreateWidget("exit-emulator", smeBSBObjectClass, gui->file_pldn, arglist, argcount);
723 XtAddCallback(gui->exit_emulator, XtNcallback, (XtCallbackProc) OnExitEmulatorCbk, (XtPointer) gui);
724 XtManageChild(gui->exit_emulator);
725 /* ctrl-menu */
726 argcount = 0;
727 XtSetArg(arglist[argcount], XtNlabel, _("Controls")); argcount++;
728 XtSetArg(arglist[argcount], XtNmenuName, "ctrl-pldn"); argcount++;
729 gui->ctrl_menu = XtCreateWidget("ctrl-menu", menuButtonWidgetClass, gui->menu_bar, arglist, argcount);
730 XtManageChild(gui->ctrl_menu);
731 /* ctrl-pldn */
732 argcount = 0;
733 gui->ctrl_pldn = XtCreatePopupShell("ctrl-pldn", simpleMenuWidgetClass, gui->ctrl_menu, arglist, argcount);
734 /* pause-emu */
735 argcount = 0;
736 XtSetArg(arglist[argcount], XtNlabel, _("Play / Pause")); argcount++;
737 gui->pause_emu = XtCreateWidget("pause-emu", smeBSBObjectClass, gui->ctrl_pldn, arglist, argcount);
738 XtAddCallback(gui->pause_emu, XtNcallback, (XtCallbackProc) OnPauseCbk, (XtPointer) gui);
739 XtManageChild(gui->pause_emu);
740 /* reset-emu */
741 argcount = 0;
742 XtSetArg(arglist[argcount], XtNlabel, _("Reset")); argcount++;
743 gui->reset_emu = XtCreateWidget("reset-emu", smeBSBObjectClass, gui->ctrl_pldn, arglist, argcount);
744 XtAddCallback(gui->reset_emu, XtNcallback, (XtCallbackProc) OnResetCbk, (XtPointer) gui);
745 XtManageChild(gui->reset_emu);
746 /* help-menu */
747 argcount = 0;
748 XtSetArg(arglist[argcount], XtNlabel, _("Help")); argcount++;
749 XtSetArg(arglist[argcount], XtNmenuName, "help-pldn"); argcount++;
750 gui->help_menu = XtCreateWidget("help-menu", menuButtonWidgetClass, gui->menu_bar, arglist, argcount);
751 XtManageChild(gui->help_menu);
752 /* help-pldn */
753 argcount = 0;
754 gui->help_pldn = XtCreatePopupShell("help-pldn", simpleMenuWidgetClass, gui->help_menu, arglist, argcount);
755 /* legal-info */
756 argcount = 0;
757 XtSetArg(arglist[argcount], XtNlabel, _("Legal Info")); argcount++;
758 gui->legal_info = XtCreateWidget("legal-info", smeBSBObjectClass, gui->help_pldn, arglist, argcount);
759 XtAddCallback(gui->legal_info, XtNcallback, (XtCallbackProc) OnLegalInfoCbk, (XtPointer) gui);
760 XtManageChild(gui->legal_info);
761 /* separator4 */
762 argcount = 0;
763 gui->separator4 = XtCreateWidget("separator4", smeLineObjectClass, gui->help_pldn, arglist, argcount);
764 XtManageChild(gui->separator4);
765 /* about-xcpc */
766 argcount = 0;
767 XtSetArg(arglist[argcount], XtNlabel, _("About Xcpc")); argcount++;
768 gui->about_xcpc = XtCreateWidget("about-xcpc", smeBSBObjectClass, gui->help_pldn, arglist, argcount);
769 XtAddCallback(gui->about_xcpc, XtNcallback, (XtCallbackProc) OnAboutXcpcCbk, (XtPointer) gui);
770 XtManageChild(gui->about_xcpc);
771 /* emulator */
772 argcount = 0;
773 XtSetArg(arglist[argcount], XtNemuStartHandler, amstrad_cpc_start_handler); argcount++;
774 XtSetArg(arglist[argcount], XtNemuClockHandler, amstrad_cpc_clock_handler); argcount++;
775 XtSetArg(arglist[argcount], XtNemuCloseHandler, amstrad_cpc_close_handler); argcount++;
776 XtSetArg(arglist[argcount], XtNemuInputHandler, amstrad_cpc_input_handler); argcount++;
777 XtSetArg(arglist[argcount], XtNemuPaintHandler, amstrad_cpc_paint_handler); argcount++;
778 gui->emulator = XemCreateEmulator(gui->main_wnd, "emulator", arglist, argcount);
779 XtManageChild(gui->emulator);
780 /* XXX */
781 XtAddCallback(toplevel, XtNdropURICallback, (XtCallbackProc) OnDropURICbk, (XtPointer) gui);
782 return(gui->main_wnd);
783 }
784