4
** Copyright (c) 1993-2001 by Hans-Ulrich Kiel & Joerg Czeranski
5
** All rights reserved.
7
** Redistribution and use in source and binary forms, with or without
8
** modification, are permitted provided that the following conditions are
11
** 1. Redistributions of source code must retain the above copyright
12
** notice, this list of conditions and the following disclaimer.
13
** 2. Redistributions in binary form must reproduce the above copyright
14
** notice, this list of conditions and the following disclaimer in the
15
** documentation and/or other materials provided with the distribution.
16
** 3. The name of the authors may not be used to endorse or promote
17
** products derived from this software without specific prior written
19
** 4. The name ``iMaze'' may not be used for products derived from this
20
** software unless a prefix or a suffix is added to the name.
22
** THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
23
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
** DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
26
** INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
30
** STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
31
** IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
** POSSIBILITY OF SUCH DAMAGE.
35
** Datei: Xt_fenster.c
38
** Fensterverwaltung auf Basis des X Toolkit,
39
** wird fuer Motif und Athena verwendet
46
#include <X11/Intrinsic.h>
47
#include <X11/StringDefs.h>
48
#include <X11/Shell.h>
53
#include "ereignisse.h"
61
#include "Xt_appdefs.h"
63
#include "Xt_fenster.h"
65
static char sccsid[] = "@(#)Xt_fenster.c 3.18 12/05/01";
68
#define STR_LENGTH 256
71
struct arg_option einaus_opts[] =
73
{ Arg_Include, NULL, X_eingabe_opts },
74
{ Arg_Include, NULL, audio_opts },
79
/* application resources */
80
static struct res_data
82
char *audio_directory;
84
static XtResource res_list[] =
91
XtOffsetOf(struct res_data, audio_directory),
93
"" /* use DEFAULT_SOUND_DIR in audio.c */
97
static int toplevel_exists = 0;
99
static struct blickfelddaten frontview_data;
100
static struct blickfelddaten rearview_data;
101
static int compass_data;
102
static struct punktedaten score_data;
103
static struct grundrissdaten map_data;
105
static int connected = 0;
107
static int network_proc_active = 0;
108
static XtInputId network_proc_id;
110
static XtInputId audio_select_id;
112
static int audio_is_active = 0;
113
static int audio_select_pending = 0;
115
static void (*audio_signal_handler)(void) = NULL;
118
static void audio_select_handler(XtPointer function, int *descriptor,
121
((void (*)(void))function)();
125
static void handle_audio_signal(int signal)
127
if (audio_signal_handler != NULL)
128
audio_signal_handler();
132
static void popdown_view(struct xt_view *view)
142
static void view_redraw(struct xt_view *view)
144
X_zeichne_sync_anfang(view->window.display);
145
view->redraw(view->X_data, &view->window, view->data);
146
X_zeichne_sync_ende(view->window.display);
150
static void set_pause_mode(int in_pause)
154
XtSetArg(arglist[0], XtNsensitive, !in_pause);
155
XtSetValues(xt_pause_button_w, arglist, 1);
157
XtSetArg(arglist[0], XtNsensitive, in_pause);
158
XtSetValues(xt_resume_button_w, arglist, 1);
162
static void stop_network_proc(void)
164
if (!network_proc_active)
167
network_proc_active = 0;
168
XtRemoveInput(network_proc_id);
170
xt_frontview.was_open = xt_frontview.is_open;
171
xt_rearview.was_open = xt_rearview.is_open;
172
xt_compassview.was_open = xt_compassview.is_open;
173
xt_scoreview.was_open = xt_scoreview.is_open;
174
xt_mapview.was_open = xt_mapview.is_open;
178
static void finish_disconnect(void)
182
XtSetArg(arglist[0], XtNsensitive, False);
183
XtSetValues(xt_disconnect_button_w, arglist, 1);
184
XtSetValues(xt_pause_button_w, arglist, 1);
185
XtSetValues(xt_resume_button_w, arglist, 1);
189
popdown_view(&xt_rearview);
190
popdown_view(&xt_compassview);
191
popdown_view(&xt_scoreview);
192
popdown_view(&xt_mapview);
194
frontview_data.titelbild = 1;
195
if (xt_frontview.is_open)
196
view_redraw(&xt_frontview);
198
xt_set_status_label("Not connected");
199
xt_set_option_sensitivity(True);
203
static void do_disconnect(void)
207
char status_msg[STR_LENGTH];
214
XtSetArg(arglist[0], XtNsensitive, False);
215
XtSetValues(xt_disconnect_button_w, arglist, 1);
216
XtSetValues(xt_pause_button_w, arglist, 1);
217
XtSetValues(xt_resume_button_w, arglist, 1);
221
popdown_view(&xt_rearview);
222
popdown_view(&xt_compassview);
223
popdown_view(&xt_scoreview);
224
popdown_view(&xt_mapview);
226
frontview_data.titelbild = 1;
227
if (xt_frontview.is_open)
228
view_redraw(&xt_frontview);
230
server_name = xt_get_string_value(xt_server_field_w);
232
strcpy(status_msg, "Disconnecting from ");
233
strncat(status_msg, server_name,
234
sizeof status_msg - strlen(status_msg));
236
xt_set_status_label(status_msg);
238
XFlush(XtDisplay(xt_toplevel));
240
client_spiel_beenden();
242
xt_set_status_label("Not connected");
243
xt_set_option_sensitivity(True);
247
static void network_ready_handler(XtPointer data, int *source, XtInputId *id)
251
char **error_message;
254
milden_fehler_abfragen(&error_message, &button_label);
255
ueblen_fehler_anzeigen(error_message, button_label);
265
static Boolean connect_work_proc(XtPointer closure)
268
char server_name[STR_LENGTH], message_name[STR_LENGTH];
269
char status_msg[STR_LENGTH];
276
strncpy(server_name, xt_get_string_value(xt_server_field_w),
278
server_name[sizeof server_name - 1] = 0;
280
strncpy(message_name, xt_get_string_value(xt_message_field_w),
281
sizeof message_name);
282
message_name[sizeof message_name - 1] = 0;
284
camera_mode = xt_get_toggle_value(xt_camera_toggle_w);
286
if (client_spiel_starten(server_name, message_name, camera_mode))
288
char **error_message;
291
milden_fehler_abfragen(&error_message, &button_label);
292
ueblen_fehler_anzeigen(error_message, button_label);
298
if ((descriptor = bewegung_deskriptor()) != NULL)
300
network_proc_id = XtAppAddInput(xt_app_context, *descriptor,
301
(XtPointer)XtInputReadMask, network_ready_handler,
303
network_proc_active = 1;
307
frontview_data.titelbild = 0;
309
if (xt_frontview.was_open)
310
xt_popup_view(&xt_frontview);
312
if (xt_rearview.was_open)
313
xt_popup_view(&xt_rearview);
315
if (xt_compassview.was_open)
316
xt_popup_view(&xt_compassview);
318
if (xt_scoreview.was_open)
319
xt_popup_view(&xt_scoreview);
321
if (xt_mapview.was_open)
322
xt_popup_view(&xt_mapview);
324
strcpy(status_msg, "Connected to ");
325
strncat(status_msg, server_name,
326
sizeof status_msg - strlen(status_msg));
328
xt_set_status_label(status_msg);
330
XtSetArg(arglist[0], XtNsensitive, True);
331
XtSetValues(xt_disconnect_button_w, arglist, 1);
338
static void destroy_handler(Widget widget, XtPointer client_data,
347
/* bis hier lokaler Teil */
348
/***********************************************/
349
/* ab hier globaler Teil */
352
void xt_view_init(struct xt_view *view)
355
Dimension width, height;
358
XtSetArg(arglist[0], XtNwidth, &width);
359
XtSetArg(arglist[1], XtNheight, &height);
360
XtSetArg(arglist[2], XtNdepth, &depth);
362
XtGetValues(view->w, arglist, 3);
364
view->window.breite = width;
365
view->window.hoehe = height;
366
view->window.farbtiefe = depth;
368
view->init(&view->X_data, &view->window);
372
void xt_view_resize(Widget widget, XtPointer client_data, XtPointer call_data)
374
struct xt_view *view;
376
view = (struct xt_view *)client_data;
377
X_zeichne_sync_anfang(view->window.display);
378
X_fenster_freigeben(&view->X_data, &view->window);
380
X_zeichne_sync_ende(view->window.display);
384
void xt_view_redraw(Widget widget, XtPointer client_data, XtPointer call_data)
386
struct xt_view *view;
388
view = (struct xt_view *)client_data;
389
X_zeichne_sync_anfang(view->window.display);
390
view->redraw(view->X_data, &view->window, view->data);
391
X_zeichne_sync_ende(view->window.display);
395
void xt_view_destroy(Widget widget, XtPointer client_data, XtPointer call_data)
397
struct xt_view *view;
399
view = (struct xt_view *)client_data;
402
view->is_initialized = 0;
406
void xt_view_toggle(Widget widget, XtPointer client_data, XtPointer call_data)
408
struct xt_view *view;
410
view = (struct xt_view *)client_data;
419
void xt_disconnect_handler(Widget widget, XtPointer client_data,
426
void xt_connect_handler(Widget widget, XtPointer client_data,
430
char status_msg[STR_LENGTH];
435
xt_set_option_sensitivity(False);
437
server_name = xt_get_string_value(xt_server_field_w);
439
strcpy(status_msg, "Connecting to ");
440
strncat(status_msg, server_name,
441
sizeof status_msg - strlen(status_msg));
443
xt_set_status_label(status_msg);
445
XtAppAddWorkProc(xt_app_context, connect_work_proc, NULL);
446
XSync(XtDisplay(xt_toplevel), False);
450
void xt_pause_handler(Widget widget, XtPointer client_data,
453
eingabe_simulieren(STOPSIGNAL);
457
void xt_resume_handler(Widget widget, XtPointer client_data,
460
eingabe_simulieren(WEITERSIGNAL);
464
void xt_exit_handler(Widget widget, XtPointer client_data, XtPointer call_data)
468
XtDestroyWidget(xt_toplevel);
472
void zeichne_sync_anfang(void)
474
X_zeichne_sync_anfang(XtDisplay(xt_toplevel));
478
void zeichne_sync_ende(void)
480
X_zeichne_sync_ende(XtDisplay(xt_toplevel));
484
void zeichne_blickfeld(struct objektdaten *objekte_neu)
486
objekte_kopieren(&frontview_data.objekte, objekte_neu);
488
if (xt_frontview.is_open)
489
X_zeichne_blickfeld(xt_frontview.X_data, &xt_frontview.window,
494
void zeichne_rueckspiegel(struct objektdaten *objekte_rueck_neu)
496
objekte_kopieren(&rearview_data.objekte, objekte_rueck_neu);
498
if (xt_rearview.is_open)
499
X_zeichne_blickfeld(xt_rearview.X_data, &xt_rearview.window,
504
void zeichne_karte(int spieler_index, int anzkreise_neu,
505
struct kartenkreis *kreise_neu)
507
map_data.anzkreise_alt = map_data.anzkreise;
508
map_data.kreise_alt = map_data.kreise;
509
liste_kopieren(&map_data.anzkreise, (void **)&map_data.kreise,
510
&anzkreise_neu, (void **)&kreise_neu,
511
sizeof(struct kartenkreis));
513
if (xt_mapview.is_open)
514
X_zeichne_karte(xt_mapview.X_data, &xt_mapview.window,
517
liste_freigeben(&map_data.anzkreise_alt,
518
(void **)&map_data.kreise_alt);
519
map_data.anzkreise_alt = 0;
520
map_data.kreise_alt = NULL;
524
void zeichne_grundriss(int anzlinien_neu, struct kartenlinie *linien_neu)
526
liste_freigeben(&map_data.anzlinien, (void **)&map_data.linien);
527
liste_kopieren(&map_data.anzlinien, (void **)&map_data.linien,
528
&anzlinien_neu, (void **)&linien_neu,
529
sizeof(struct kartenlinie));
531
if (xt_mapview.is_open)
532
X_zeichne_grundriss(xt_mapview.X_data, &xt_mapview.window,
537
void zeichne_kompass(int blickrichtung_neu)
539
compass_data = blickrichtung_neu;
541
if (xt_compassview.is_open)
542
X_zeichne_kompass(xt_compassview.X_data,
543
&xt_compassview.window, &compass_data);
547
void zeichne_punkte(struct punktedaten *punkte_neu)
549
liste_freigeben(&score_data.anzpunkte, (void **)&score_data.punkte);
550
liste_kopieren(&score_data.anzpunkte, (void **)&score_data.punkte,
551
&punkte_neu->anzpunkte, (void **)&punkte_neu->punkte,
552
sizeof(struct punktestand));
554
if (xt_scoreview.is_open)
555
X_zeichne_punkte(xt_scoreview.X_data, &xt_scoreview.window,
560
void grafik_schleife(void)
564
XtAppMainLoop(xt_app_context);
568
int grafik_init(int *argc, char **argv)
575
xt_toplevel = XtAppInitialize(&xt_app_context, "IMaze",
576
NULL, 0, argc, argv, fallback_app_resources, NULL, 0);
577
XtAddCallback(xt_toplevel, XtNdestroyCallback, destroy_handler, NULL);
581
XtGetApplicationResources(xt_toplevel, (XtPointer)&res_data,
582
res_list, XtNumber(res_list), NULL, 0);
584
xt_fill_main(xt_toplevel);
585
XtRealizeWidget(xt_toplevel);
587
XtSetArg(xt_icon_arglist[0], XtNiconPixmap,
588
X_create_icon_pixmap(XtDisplay(xt_toplevel),
589
XScreenNumberOfScreen(XtScreen(xt_toplevel))));
591
XtSetValues(xt_toplevel, xt_icon_arglist, 1);
593
if (X_farben_init(XtDisplay(xt_toplevel),
594
XScreenNumberOfScreen(XtScreen(xt_toplevel)), &colormap))
596
XtRemoveCallback(xt_toplevel, XtNdestroyCallback,
597
destroy_handler, NULL);
598
XtDestroyWidget(xt_toplevel);
605
XtSetArg(arglist[0], XtNcolormap, colormap);
606
XtSetValues(xt_toplevel, arglist, 1);
608
xt_frontview.name = "frontView";
609
xt_frontview.data = &frontview_data;
610
xt_frontview.is_open = 0;
611
xt_frontview.is_initialized = 0;
612
xt_frontview.was_open = 1;
613
xt_frontview.init = X_fenster_init;
614
xt_frontview.redraw = X_zeichne_blickfeld;
615
objekt_listen_init(&frontview_data.objekte);
616
frontview_data.fadenkreuz = 1;
617
frontview_data.titelbild = 1;
619
xt_scoreview.name = "score";
620
xt_scoreview.data = &score_data;
621
xt_scoreview.is_open = 0;
622
xt_scoreview.is_initialized = 0;
623
xt_scoreview.was_open = 1;
624
xt_scoreview.init = X_fenster_init;
625
xt_scoreview.redraw = X_zeichne_punkte;
626
liste_initialisieren(&score_data.anzpunkte,
627
(void **)&score_data.punkte);
629
xt_compassview.name = "compass";
630
xt_compassview.data = &compass_data;
631
xt_compassview.is_open = 0;
632
xt_compassview.is_initialized = 0;
633
xt_compassview.was_open = 0;
634
xt_compassview.init = X_fenster_init;
635
xt_compassview.redraw = X_zeichne_kompass;
638
xt_rearview.name = "rearView";
639
xt_rearview.data = &rearview_data;
640
xt_rearview.is_open = 0;
641
xt_rearview.is_initialized = 0;
642
xt_rearview.was_open = 0;
643
xt_rearview.init = X_fenster_init;
644
xt_rearview.redraw = X_zeichne_blickfeld;
645
objekt_listen_init(&rearview_data.objekte);
646
rearview_data.fadenkreuz = 0;
647
rearview_data.titelbild = 0;
649
xt_mapview.name = "map";
650
xt_mapview.data = &map_data;
651
xt_mapview.is_open = 0;
652
xt_mapview.is_initialized = 0;
653
xt_mapview.was_open = 0;
654
xt_mapview.init = X_karte_init;
655
xt_mapview.redraw = X_zeichne_grundriss;
656
liste_initialisieren(&map_data.anzlinien, (void **)&map_data.linien);
657
liste_initialisieren(&map_data.anzkreise, (void **)&map_data.kreise);
658
map_data.anzkreise_alt = 0;
659
map_data.kreise_alt = NULL;
661
if (X_eingabe_init())
664
xt_popup_view(&xt_frontview);
666
switch (audio_start(res_data.audio_directory))
682
void grafik_ende(void)
685
XtDestroyWidget(xt_toplevel);
689
if (!audio_is_active)
697
void ueblen_fehler_anzeigen(char **meldung, char *knopf)
699
if (!toplevel_exists)
701
while (*meldung != NULL)
702
fprintf(stderr, "iMaze: %s\n", *meldung++);
713
xt_request_window(meldung, knopf, NULL, 0, "error");
717
void ereignisse_darstellen(char ereignisse[ERG_ANZ])
719
if (ereignisse[PAUSE_ERG])
721
else if (ereignisse[ERWACHT_ERG])
726
audio_play(ereignisse);
730
if (ereignisse[ABGESCHOSSEN_ERG] || ereignisse[GETROFFEN_ERG] ||
731
ereignisse[AKTION_FEHLER_ERG] || ereignisse[SUSPENDIERT_ERG])
732
XBell(XtDisplay(xt_toplevel), 0);
736
int rueckfrage(char **meldung, char *weiter_knopf, char *abbruch_knopf)
738
if (!toplevel_exists)
740
static char *message[] = { "iMaze - Fatal Error", "",
741
"Couldn't open notice window.", NULL };
743
uebler_fehler(message, NULL);
746
return xt_request_window(meldung, weiter_knopf,
747
abbruch_knopf, 1, "question") == 1;
751
void disconnect_abfrage(void)
753
static char *message[] = { "Do you really want do disconnect?", NULL };
755
if (!rueckfrage(message, "Sure", "Play on"))
762
void audio_select_descriptor(int descriptor, void (*function)(void),
765
if (audio_select_pending)
767
XtRemoveInput(audio_select_id);
768
audio_select_pending = 0;
771
if (function != NULL)
773
audio_select_id = XtAppAddInput(xt_app_context, descriptor,
774
for_output ? (XtPointer)XtInputWriteMask :
775
(XtPointer)XtInputReadMask,
776
audio_select_handler, (XtPointer)function);
777
audio_select_pending = 1;
782
void audio_handle_signal(int signal, void (*function)(void))
784
audio_signal_handler = function;
786
if (audio_signal_handler == NULL)
787
handle_signal(signal, SIG_DFL);
789
handle_signal(signal, handle_audio_signal);