1ac0e2362295a0cb2b5a69fc83cc53a6aab59dd9
[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 types.
17  */
18 #include <stdlib.h>
19 #include <X11/Intrinsic.h>
20 #include <X11/StringDefs.h>
21 #include <X11/Shell.h>
22 #include <X11/Xaw/Box.h>
23 #include <X11/Xaw/Form.h>
24 #include <X11/Xaw/Command.h>
25 #include <X11/Xaw/AsciiText.h>
26 #include "sst.h"
27
28 static XtAppContext app_context;
29 static Widget toplevel, text, form; 
30 static Widget navigation, weapons, planets, misc; 
31 static Widget navlabel, weaplabel, planlabel, misclabel;
32
33 static String fallback[] = {
34     "*text.resizable: true",
35     "*text.resize: ResizeBoth",
36     "*text.width: 640",
37     "*text.height: 200",
38     "*text.autoFill: True",
39     "*text.scrollVertical: Always",
40     "*text.scrollHorizontal: WhenNeeded",
41     "*text.displayCaret: True",
42     "*navigation.fromVert: text",
43     "*navigation.borderWidth: 0",
44     "*navlabel.label: Navigation:   ",
45     "*navlabel.borderWidth: 0",
46     "*weapons.fromVert: navigation",
47     "*weapons.borderWidth: 0",
48     "*weaplabel.label: Weapons:      ",
49     "*weaplabel.borderWidth: 0",
50     "*planets.fromVert: weapons",
51     "*planets.borderWidth: 0",
52     "*planlabel.label: Planets:      ",
53     "*planlabel.borderWidth: 0",
54     "*misc.fromVert: planets",
55     "*misc.borderWidth: 0",
56     "*misclabel.label: Miscellaneous:",
57     "*misclabel.borderWidth: 0",
58     NULL,
59 };
60
61 struct cmd_t {
62     char *name;
63     void (*callback)(Widget, XtPointer, XtPointer);
64     Widget *parent;
65     int enable;
66     Widget widget;
67
68 };
69
70 static void quit_proc(Widget w, XtPointer client_data, XtPointer call_data)
71
72     XtDestroyApplicationContext (app_context);
73     exit (0);
74 }
75
76 static void text_append_to(Widget w, String str)
77 /* append text to a specified text widget */
78 {
79     XawTextBlock txtblk;
80     XawTextPosition textend = XawTextGetInsertionPoint(w);
81
82     txtblk.ptr = str;
83     txtblk.length = strlen(str);
84     txtblk.firstPos = 0;
85     txtblk.format = FMT8BIT;
86
87     XawTextReplace(w, textend, textend, &txtblk);
88 }
89
90 static void noargs_proc(Widget w, XtPointer client_data, XtPointer call_data)
91 /* use this for commands that take no arguments */
92 {
93     /* currently a stub */
94     text_append_to(w, XtName(w));
95     printf("Button %s pressed\n", XtName(w));
96 }
97
98 static struct cmd_t commands[] = {
99     {"Move",            NULL,           &navigation,    0},
100     {"Dock",            noargs_proc,    &navigation,    0},
101     {"Chart",           noargs_proc,    &navigation,    0},
102     {"Impulse",         NULL,           &navigation,    0},
103     {"Rest",            NULL,           &navigation,    0},
104     {"Warp",            NULL,           &navigation,    0},
105     {"Probe",           NULL,           &navigation,    OPTION_PROBE},
106
107     {"Phasers",         NULL,           &weapons,       0},
108     {"Torpedo",         NULL,           &weapons,       0},
109     {"Shields",         NULL,           &weapons,       0},
110     {"Damages",         noargs_proc,    &weapons,       0},
111     {"Abandon",         noargs_proc,    &weapons,       0},
112     {"Destruct",        noargs_proc,    &weapons,       0},
113     {"Deathray",        noargs_proc,    &weapons,       0},
114     {"Mayday",          noargs_proc,    &weapons,       0},
115
116     {"Sensors",         noargs_proc,    &planets,       OPTION_PLANETS},
117     {"Orbit",           noargs_proc,    &planets,       OPTION_PLANETS},
118     {"Transport",       noargs_proc,    &planets,       OPTION_PLANETS},
119     {"Mine",            noargs_proc,    &planets,       OPTION_PLANETS},
120     {"Crystals",        noargs_proc,    &planets,       OPTION_PLANETS},
121     {"Shuttle",         noargs_proc,    &planets,       OPTION_PLANETS},
122     {"Planets",         noargs_proc,    &planets,       OPTION_PLANETS},
123
124     {"Score",           noargs_proc,    &misc,          0},
125     {"Report",          noargs_proc,    &misc,          0},
126     {"Computer",        noargs_proc,    &misc,          0},
127     {"Save",            NULL,           &misc,          0},
128     {"Quit",            quit_proc,      &misc,          0},
129     {"Help",            noargs_proc,    &misc,          0},
130 };
131
132 static void instantiate_main(int argc, char **argv)
133
134     struct cmd_t *cp;
135
136     toplevel = XtVaOpenApplication(&app_context, "sst2k", NULL, 0, &argc,
137                                     argv, fallback, 
138                                     applicationShellWidgetClass,
139                                     XtNallowShellResize, True, NULL);
140     form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, NULL);
141     /* the command window */
142     text = XtVaCreateManagedWidget("text", 
143                                    asciiTextWidgetClass, form,
144                                    XtNeditType, XawtextEdit,
145                                    NULL);
146     /* The button panels */
147     navigation  = XtVaCreateManagedWidget("navigation", 
148                                           boxWidgetClass, form,
149                                           XtNorientation, XtorientHorizontal,
150                                           NULL); 
151     navlabel  = XtVaCreateManagedWidget("navlabel", 
152                                         labelWidgetClass, navigation,
153                                         NULL); 
154     weapons  = XtVaCreateManagedWidget("weapons", 
155                                        boxWidgetClass, form,
156                                        XtNorientation, XtorientHorizontal,
157                                        NULL); 
158     weaplabel  = XtVaCreateManagedWidget("weaplabel", 
159                                          labelWidgetClass, weapons,
160                                          NULL); 
161     planets  = XtVaCreateManagedWidget("planets", 
162                                        boxWidgetClass, form,
163                                        XtNorientation, XtorientHorizontal,
164                                        NULL); 
165     planlabel  = XtVaCreateManagedWidget("planlabel", 
166                                          labelWidgetClass, planets,
167                                          XtNborderWidth, 0,
168                                          NULL); 
169     misc  = XtVaCreateManagedWidget("misc", 
170                                        boxWidgetClass, form,
171                                        XtNorientation, XtorientHorizontal,
172                                        NULL); 
173     misclabel  = XtVaCreateManagedWidget("misclabel", 
174                                          labelWidgetClass, misc,
175                                          NULL); 
176     for (cp = commands; cp < commands + sizeof(commands)/sizeof(commands[0]); cp++) {
177         cp->widget = XtVaCreateManagedWidget(cp->name, 
178                                              commandWidgetClass, 
179                                              *cp->parent, 
180                                              XtNlabel, cp->name,
181                                              NULL);
182         if (cp->callback)
183             XtAddCallback (cp->widget, XtNcallback, cp->callback, NULL);
184     }
185     XtRealizeWidget(toplevel);
186     XtAppMainLoop(app_context);
187     /* loop may be interrupted */
188     XtDestroyApplicationContext(app_context);
189 }
190
191 int main(int argc, char **argv)
192 {
193     instantiate_main(argc, argv);
194     exit(0);
195 }