Replace more #defines with enums.
[super-star-trek.git] / src / xio.c
1 /*
2  * Problems with this code:
3  *   1. The text window behaves like it's only a few lines high, 
4  *      scrolling in response to Return when the insertion point 
5  *      is nowhere near the last line.
6  *   2. The attempt to insert text with XawTextReplace() core dumps.
7  *   3. I haven't found a way to write a callback that triggers on Return 
8  *      and yields the line before the return.  The explanation at
9  *      http://www.linuxjunkies.org/programming/GUI/xwindow/x11/text.html
10  *      hints that this may be difficult.
11  *
12  * The functional goal is this:
13  *    1. Button pushes should be able to insert commands at the buffer's
14  *       current insertion point.
15  *    2. When a user finishes a command with Return, a callback should
16  *       receive the line of input typed.
17  * 
18  * All the input passed to the game in back of this will be lines full
19  * of commands generated either by typing into the text buffer directly 
20  * or by button presses that generate text unto the buffer.
21  */
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <X11/Intrinsic.h>
25 #include <X11/StringDefs.h>
26 #include <X11/Shell.h>
27 #include <X11/Xaw/Box.h>
28 #include <X11/Xaw/Form.h>
29 #include <X11/Xaw/Command.h>
30 #include <X11/Xaw/AsciiText.h>
31 //#include "sst.h"
32 #define OPTION_PLANETS  1
33 #define OPTION_PROBE    2
34
35 static XtAppContext app_context;
36 static Widget toplevel, text, form; 
37 static Widget navigation, weapons, planets, misc; 
38 static Widget navlabel, weaplabel, planlabel, misclabel;
39
40 static String fallback[] = {
41     "*text.resizable: true",
42     "*text.resize: ResizeBoth",
43     "*text.width: 640",
44     "*text.height: 200",
45     "*text.autoFill: True",
46     "*text.scrollVertical: Always",
47     "*text.scrollHorizontal: WhenNeeded",
48     "*text.displayCaret: True",
49     "*navigation.fromVert: text",
50     "*navigation.borderWidth: 0",
51     "*navlabel.label: Navigation:   ",
52     "*navlabel.borderWidth: 0",
53     "*weapons.fromVert: navigation",
54     "*weapons.borderWidth: 0",
55     "*weaplabel.label: Weapons:      ",
56     "*weaplabel.borderWidth: 0",
57     "*planets.fromVert: weapons",
58     "*planets.borderWidth: 0",
59     "*planlabel.label: Planets:      ",
60     "*planlabel.borderWidth: 0",
61     "*misc.fromVert: planets",
62     "*misc.borderWidth: 0",
63     "*misclabel.label: Miscellaneous:",
64     "*misclabel.borderWidth: 0",
65     NULL,
66 };
67
68 struct cmd_t {
69     char *name;
70     void (*callback)(Widget, XtPointer, XtPointer);
71     Widget *parent;
72     int enable;
73     Widget widget;
74
75 };
76
77 static void quit_proc(Widget w, XtPointer client_data, XtPointer call_data)
78
79     XtDestroyApplicationContext (app_context);
80     exit (0);
81 }
82
83 static void text_append_to(Widget w, String str)
84 /* append text to a specified text widget */
85 {
86     XawTextBlock txtblk;
87     XawTextPosition textend = XawTextGetInsertionPoint(w);
88
89     txtblk.ptr = str;
90     txtblk.length = strlen(str);
91     txtblk.firstPos = 0;
92     txtblk.format = FMT8BIT;
93
94     XawTextReplace(w, textend, textend, &txtblk);
95 }
96
97 static void noargs_proc(Widget w, XtPointer client_data, XtPointer call_data)
98 /* use this for commands that take no arguments */
99 {
100     /* currently a stub */
101     text_append_to(w, XtName(w));
102     printf("Button %s pressed\n", XtName(w));
103 }
104
105 static struct cmd_t commands[] = {
106     {"Move",            NULL,           &navigation,    0},
107     {"Dock",            noargs_proc,    &navigation,    0},
108     {"Chart",           noargs_proc,    &navigation,    0},
109     {"Impulse",         NULL,           &navigation,    0},
110     {"Rest",            NULL,           &navigation,    0},
111     {"Warp",            NULL,           &navigation,    0},
112     {"Probe",           NULL,           &navigation,    OPTION_PROBE},
113
114     {"Phasers",         NULL,           &weapons,       0},
115     {"Torpedo",         NULL,           &weapons,       0},
116     {"Shields",         NULL,           &weapons,       0},
117     {"Damages",         noargs_proc,    &weapons,       0},
118     {"Abandon",         noargs_proc,    &weapons,       0},
119     {"Destruct",        noargs_proc,    &weapons,       0},
120     {"Deathray",        noargs_proc,    &weapons,       0},
121     {"Mayday",          noargs_proc,    &weapons,       0},
122
123     {"Sensors",         noargs_proc,    &planets,       OPTION_PLANETS},
124     {"Orbit",           noargs_proc,    &planets,       OPTION_PLANETS},
125     {"Transport",       noargs_proc,    &planets,       OPTION_PLANETS},
126     {"Mine",            noargs_proc,    &planets,       OPTION_PLANETS},
127     {"Crystals",        noargs_proc,    &planets,       OPTION_PLANETS},
128     {"Shuttle",         noargs_proc,    &planets,       OPTION_PLANETS},
129     {"Planets",         noargs_proc,    &planets,       OPTION_PLANETS},
130
131     {"Score",           noargs_proc,    &misc,          0},
132     {"Report",          noargs_proc,    &misc,          0},
133     {"Computer",        noargs_proc,    &misc,          0},
134     {"Save",            NULL,           &misc,          0},
135     {"Quit",            quit_proc,      &misc,          0},
136     {"Help",            noargs_proc,    &misc,          0},
137 };
138
139 static void instantiate_main(int argc, char **argv)
140
141     struct cmd_t *cp;
142
143     toplevel = XtVaOpenApplication(&app_context, "sst2k", NULL, 0, &argc,
144                                     argv, fallback, 
145                                     applicationShellWidgetClass,
146                                     XtNallowShellResize, True, NULL);
147     form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, NULL);
148     /* the command window */
149     text = XtVaCreateManagedWidget("text", 
150                                    asciiTextWidgetClass, form,
151                                    XtNeditType, XawtextEdit,
152                                    NULL);
153     /* The button panels */
154     navigation  = XtVaCreateManagedWidget("navigation", 
155                                           boxWidgetClass, form,
156                                           XtNorientation, XtorientHorizontal,
157                                           NULL); 
158     navlabel  = XtVaCreateManagedWidget("navlabel", 
159                                         labelWidgetClass, navigation,
160                                         NULL); 
161     weapons  = XtVaCreateManagedWidget("weapons", 
162                                        boxWidgetClass, form,
163                                        XtNorientation, XtorientHorizontal,
164                                        NULL); 
165     weaplabel  = XtVaCreateManagedWidget("weaplabel", 
166                                          labelWidgetClass, weapons,
167                                          NULL); 
168     planets  = XtVaCreateManagedWidget("planets", 
169                                        boxWidgetClass, form,
170                                        XtNorientation, XtorientHorizontal,
171                                        NULL); 
172     planlabel  = XtVaCreateManagedWidget("planlabel", 
173                                          labelWidgetClass, planets,
174                                          XtNborderWidth, 0,
175                                          NULL); 
176     misc  = XtVaCreateManagedWidget("misc", 
177                                        boxWidgetClass, form,
178                                        XtNorientation, XtorientHorizontal,
179                                        NULL); 
180     misclabel  = XtVaCreateManagedWidget("misclabel", 
181                                          labelWidgetClass, misc,
182                                          NULL); 
183     for (cp = commands; cp < commands + sizeof(commands)/sizeof(commands[0]); cp++) {
184         cp->widget = XtVaCreateManagedWidget(cp->name, 
185                                              commandWidgetClass, 
186                                              *cp->parent, 
187                                              XtNlabel, cp->name,
188                                              NULL);
189         if (cp->callback)
190             XtAddCallback (cp->widget, XtNcallback, cp->callback, NULL);
191     }
192     XtRealizeWidget(toplevel);
193     XtAppMainLoop(app_context);
194     /* loop may be interrupted */
195     XtDestroyApplicationContext(app_context);
196 }
197
198 int main(int argc, char **argv)
199 {
200     instantiate_main(argc, argv);
201     exit(0);
202 }