Subversion Repositories eduke32

Rev

Rev 194 | Rev 212 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
194 terminx 1
/* NOTE: Glade will generate code for a dialogue box which you should
2
 * then patch into this file whenever you make a change to the Glade
3
 * template.
4
 */
5
 
6
#include <sys/types.h>
7
#include <sys/stat.h>
8
#include <unistd.h>
9
#include <string.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
 
13
#include <gdk-pixbuf/gdk-pixdata.h>
14
#include <gdk-pixbuf/gdk-pixbuf.h>
15
#include <gdk/gdkkeysyms.h>
16
#include <gtk/gtk.h>
17
 
197 terminx 18
#ifndef LINKED_GTK
19
# include "dynamicgtk.h"
20
#endif
21
 
194 terminx 22
#include "duke3d.h"
23
#include "build.h"
24
#include "compat.h"
25
#include "baselayer.h"
26
 
27
#define TAB_CONFIG 0
28
#define TAB_MESSAGES 1
29
 
30
static struct {
31
    int fullscreen;
32
    int xdim3d, ydim3d, bpp3d;
33
    int forcesetup;
34
    int usemouse, usejoy;
35
} settings;
36
 
37
extern int gtkenabled;
38
 
39
static GtkWidget *startwin = NULL;
197 terminx 40
static int retval = -1, mode = TAB_MESSAGES;
194 terminx 41
 
42
// -- SUPPORT FUNCTIONS -------------------------------------------------------
43
 
44
#define GLADE_HOOKUP_OBJECT(component,widget,name) \
45
  g_object_set_data_full (G_OBJECT (component), name, \
46
    gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref)
47
 
48
#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \
49
  g_object_set_data (G_OBJECT (component), name, widget)
50
 
51
#define lookup_widget(x,w) \
52
        (GtkWidget*) g_object_get_data(G_OBJECT(x), w)
53
 
54
static GdkPixbuf *load_banner(void)
55
{
56
    extern const GdkPixdata startbanner_pixdata;
57
    return gdk_pixbuf_from_pixdata(&startbanner_pixdata, FALSE, NULL);
58
}
59
 
60
static void SetPage(int n)
61
{
62
    if (!gtkenabled || !startwin) return;
197 terminx 63
    mode = n;
194 terminx 64
    gtk_notebook_set_current_page(GTK_NOTEBOOK(lookup_widget(startwin,"tabs")), n);
65
 
197 terminx 66
    // each control in the config page vertical layout plus the start button should be made (in)sensitive
67
    if (n == TAB_CONFIG) n = TRUE; else n = FALSE;
68
    gtk_widget_set_sensitive(lookup_widget(startwin,"startbutton"), n);
194 terminx 69
    gtk_container_foreach(GTK_CONTAINER(lookup_widget(startwin,"configvlayout")),
197 terminx 70
                          (GtkCallback)gtk_widget_set_sensitive, (gpointer)n);
194 terminx 71
}
72
 
73
static void on_vmode3dcombo_changed(GtkComboBox *, gpointer);
74
static void PopulateForm(void)
75
{
76
    int mode3d, i;
77
    GtkListStore *modes3d;
78
    GtkTreeIter iter;
79
    GtkComboBox *box3d;
80
    char buf[64];
81
 
82
    mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, settings.bpp3d, settings.fullscreen, 1);
83
    if (mode3d < 0) {
84
        int i, cd[] = { 32, 24, 16, 15, 8, 0 };
85
        for (i=0; cd[i]; ) { if (cd[i] >= settings.bpp3d) i++; else break; }
86
        for ( ; cd[i]; i++) {
87
            mode3d = checkvideomode(&settings.xdim3d, &settings.ydim3d, cd[i], settings.fullscreen, 1);
88
            if (mode3d < 0) continue;
89
            settings.bpp3d = cd[i];
90
            break;
91
        }
92
    }
93
 
94
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"fullscreencheck")), settings.fullscreen);
95
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"alwaysshowcheck")), settings.forcesetup);
96
 
97
    box3d = GTK_COMBO_BOX(lookup_widget(startwin,"vmode3dcombo"));
98
    modes3d = GTK_LIST_STORE(gtk_combo_box_get_model(box3d));
99
    gtk_list_store_clear(modes3d);
100
 
101
    for (i=0; i<validmodecnt; i++) {
102
        if (validmode[i].fs != settings.fullscreen) continue;
103
 
104
        // all modes get added to the 3D mode list
105
        Bsprintf(buf, "%ld x %ld %dbpp", validmode[i].xdim, validmode[i].ydim, validmode[i].bpp);
106
        gtk_list_store_append(modes3d, &iter);
107
        gtk_list_store_set(modes3d, &iter, 0,buf, 1,i, -1);
108
        if (i == mode3d) {
109
            g_signal_handlers_block_by_func(box3d, on_vmode3dcombo_changed, NULL);
110
            gtk_combo_box_set_active_iter(box3d, &iter);
111
            g_signal_handlers_unblock_by_func(box3d, on_vmode3dcombo_changed, NULL);
112
        }
113
    }
114
 
115
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputmousecheck")), settings.usemouse);
116
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(lookup_widget(startwin,"inputjoycheck")), settings.usejoy);
117
}
118
 
119
// -- EVENT CALLBACKS AND CREATION STUFF --------------------------------------
120
 
121
static void on_vmode3dcombo_changed(GtkComboBox *combobox, gpointer user_data)
122
{
123
    GtkTreeModel *data;
124
    GtkTreeIter iter;
125
    int val;
126
    if (!gtk_combo_box_get_active_iter(combobox, &iter)) return;
127
    if (!(data = gtk_combo_box_get_model(combobox))) return;
128
    gtk_tree_model_get(data, &iter, 1, &val, -1);
129
    settings.xdim3d = validmode[val].xdim;
130
    settings.ydim3d = validmode[val].ydim;
131
}
132
 
133
static void on_fullscreencheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
134
{
135
    settings.fullscreen = (gtk_toggle_button_get_active(togglebutton) == TRUE);
136
    PopulateForm();
137
}
138
 
139
static void on_alwaysshowcheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
140
{
141
    settings.forcesetup = (gtk_toggle_button_get_active(togglebutton) == TRUE);
142
}
143
 
144
static void on_cancelbutton_clicked(GtkButton *button, gpointer user_data)
145
{
197 terminx 146
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
147
    else quitevent++;
194 terminx 148
}
149
 
150
static void on_startbutton_clicked(GtkButton *button, gpointer user_data)
151
{
152
    retval = 1;
153
    gtk_main_quit();
154
}
155
 
156
static void on_sounddrvcombo_changed(GtkComboBox *combobox, gpointer user_data)
157
{
158
}
159
 
160
static void on_cddrvcombo_changed(GtkComboBox *combobox, gpointer user_data)
161
{
162
}
163
 
164
static void on_inputmousecheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
165
{
166
    settings.usemouse = (gtk_toggle_button_get_active(togglebutton) == TRUE);
167
}
168
 
169
static void on_inputjoycheck_toggled(GtkToggleButton *togglebutton, gpointer user_data)
170
{
171
    settings.usejoy = (gtk_toggle_button_get_active(togglebutton) == TRUE);
172
}
173
 
174
static gboolean on_startwin_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
175
{
197 terminx 176
    if (mode == TAB_CONFIG) { retval = 0; gtk_main_quit(); }
177
    else quitevent++;
194 terminx 178
    return TRUE;        // FALSE would let the event go through. we want the game to decide when to close
179
}
180
 
181
 
182
static GtkWidget *create_window(void)
183
{
184
    GtkWidget *startwin;
185
    GtkWidget *hlayout;
186
    GtkWidget *banner;
187
    GtkWidget *vlayout;
188
    GtkWidget *tabs;
189
    GtkWidget *configvlayout;
190
    GtkWidget *configlayout;
191
    GtkWidget *fullscreencheck;
192
    GtkWidget *vmode3dlabel;
193
    GtkWidget *inputdevlabel;
194
    GtkWidget *sounddrvlabel;
195
    GtkWidget *cddrvlabel;
196
    GtkWidget *sounddrvcombo;
197
    GtkWidget *cddrvcombo;
198
    GtkWidget *inputmousecheck;
199
    GtkWidget *inputjoycheck;
200
    GtkWidget *vmode3dcombo;
201
    GtkWidget *alwaysshowcheck;
202
    GtkWidget *configtab;
203
    GtkWidget *messagesscroll;
204
    GtkWidget *messagestext;
205
    GtkWidget *messagestab;
206
    GtkWidget *buttons;
207
    GtkWidget *cancelbutton;
208
    GtkWidget *cancelbuttonalign;
209
    GtkWidget *cancelbuttonlayout;
210
    GtkWidget *cancelbuttonicon;
211
    GtkWidget *cancelbuttonlabel;
212
    GtkWidget *startbutton;
213
    GtkWidget *startbuttonalign;
214
    GtkWidget *startbuttonlayout;
215
    GtkWidget *startbuttonicon;
216
    GtkWidget *startbuttonlabel;
217
    GtkAccelGroup *accel_group;
218
 
219
    accel_group = gtk_accel_group_new ();
220
 
221
    // Basic window
222
    startwin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
223
    gtk_window_set_title (GTK_WINDOW (startwin), apptitle);     // NOTE: use global app title
224
    gtk_window_set_position (GTK_WINDOW (startwin), GTK_WIN_POS_CENTER);
225
    gtk_window_set_resizable (GTK_WINDOW (startwin), FALSE);
226
    gtk_window_set_type_hint (GTK_WINDOW (startwin), GDK_WINDOW_TYPE_HINT_DIALOG);
227
 
228
    // Horizontal layout of banner and controls
229
    hlayout = gtk_hbox_new (FALSE, 0);
230
    gtk_widget_show (hlayout);
231
    gtk_container_add (GTK_CONTAINER (startwin), hlayout);
232
 
233
    // Banner
234
    {
235
        GdkPixbuf *pixbuf = load_banner();
236
        banner = gtk_image_new_from_pixbuf(pixbuf);
237
        g_object_unref((gpointer)pixbuf);
238
    }
239
    gtk_widget_show (banner);
240
    gtk_box_pack_start (GTK_BOX (hlayout), banner, FALSE, FALSE, 0);
241
    gtk_misc_set_alignment (GTK_MISC (banner), 0.5, 0);
242
 
243
    // Vertical layout of tab control and start+cancel buttons
244
    vlayout = gtk_vbox_new (FALSE, 0);
245
    gtk_widget_show (vlayout);
246
    gtk_box_pack_start (GTK_BOX (hlayout), vlayout, TRUE, TRUE, 0);
247
 
248
    // Tab control
249
    tabs = gtk_notebook_new ();
250
    gtk_widget_show (tabs);
251
    gtk_box_pack_start (GTK_BOX (vlayout), tabs, TRUE, TRUE, 0);
252
    gtk_container_set_border_width (GTK_CONTAINER (tabs), 4);
253
 
254
    // Vertical layout of config page main body
255
    configvlayout = gtk_vbox_new (FALSE, 0);
256
    gtk_widget_show (configvlayout);
257
    gtk_container_add (GTK_CONTAINER (tabs), configvlayout);
258
 
259
    // Fixed-position layout of config page controls
260
    configlayout = gtk_fixed_new ();
261
    gtk_widget_show (configlayout);
262
    gtk_box_pack_start (GTK_BOX (configvlayout), configlayout, TRUE, TRUE, 0);
263
    gtk_container_set_border_width (GTK_CONTAINER (configlayout), 6);
264
 
265
    // Fullscreen checkbox
266
    fullscreencheck = gtk_check_button_new_with_mnemonic ("_Fullscreen");
267
    gtk_widget_show (fullscreencheck);
268
    gtk_fixed_put (GTK_FIXED (configlayout), fullscreencheck, 248, 0);
269
    gtk_widget_set_size_request (fullscreencheck, 85, 29);
270
    gtk_widget_add_accelerator (fullscreencheck, "grab_focus", accel_group,
271
                                GDK_F, GDK_MOD1_MASK,
272
                                GTK_ACCEL_VISIBLE);
273
 
274
    // 3D video mode label
275
    vmode3dlabel = gtk_label_new_with_mnemonic ("_Video mode:");
276
    gtk_widget_show (vmode3dlabel);
277
    gtk_fixed_put (GTK_FIXED (configlayout), vmode3dlabel, 0, 0);
278
    gtk_widget_set_size_request (vmode3dlabel, 88, 29);
279
    gtk_misc_set_alignment (GTK_MISC (vmode3dlabel), 0, 0.5);
280
 
281
    inputdevlabel = gtk_label_new ("Input devices:");
282
    gtk_widget_show (inputdevlabel);
283
    gtk_fixed_put (GTK_FIXED (configlayout), inputdevlabel, 0, 120);
284
    gtk_widget_set_size_request (inputdevlabel, 88, 20);
285
    gtk_misc_set_alignment (GTK_MISC (inputdevlabel), 0, 0.5);
286
 
287
    sounddrvlabel = gtk_label_new_with_mnemonic ("S_ound driver:");
288
    gtk_widget_show (sounddrvlabel);
289
    gtk_fixed_put (GTK_FIXED (configlayout), sounddrvlabel, 0, 40);
290
    gtk_widget_set_size_request (sounddrvlabel, 88, 29);
291
    gtk_misc_set_alignment (GTK_MISC (sounddrvlabel), 0, 0.5);
292
 
293
    cddrvlabel = gtk_label_new_with_mnemonic ("C_D drive:");
294
    gtk_widget_show (cddrvlabel);
295
    gtk_fixed_put (GTK_FIXED (configlayout), cddrvlabel, 0, 72);
296
    gtk_widget_set_size_request (cddrvlabel, 88, 29);
297
    gtk_misc_set_alignment (GTK_MISC (cddrvlabel), 0, 0.5);
298
 
299
    sounddrvcombo = gtk_combo_box_new_text ();
300
    gtk_widget_show (sounddrvcombo);
301
    gtk_fixed_put (GTK_FIXED (configlayout), sounddrvcombo, 88, 40);
302
    gtk_widget_set_size_request (sounddrvcombo, 31, 30);
303
    gtk_widget_add_accelerator (sounddrvcombo, "grab_focus", accel_group,
304
                                GDK_O, GDK_MOD1_MASK,
305
                                GTK_ACCEL_VISIBLE);
306
 
307
    cddrvcombo = gtk_combo_box_new_text ();
308
    gtk_widget_show (cddrvcombo);
309
    gtk_fixed_put (GTK_FIXED (configlayout), cddrvcombo, 88, 72);
310
    gtk_widget_set_size_request (cddrvcombo, 31, 30);
311
 
312
    inputmousecheck = gtk_check_button_new_with_mnemonic ("Mo_use");
313
    gtk_widget_show (inputmousecheck);
314
    gtk_fixed_put (GTK_FIXED (configlayout), inputmousecheck, 88, 120);
315
    gtk_widget_set_size_request (inputmousecheck, 80, 20);
316
    gtk_widget_add_accelerator (inputmousecheck, "grab_focus", accel_group,
317
                                GDK_U, GDK_MOD1_MASK,
318
                                GTK_ACCEL_VISIBLE);
319
 
320
    inputjoycheck = gtk_check_button_new_with_mnemonic ("_Joystick");
321
    gtk_widget_show (inputjoycheck);
322
    gtk_fixed_put (GTK_FIXED (configlayout), inputjoycheck, 168, 120);
323
    gtk_widget_set_size_request (inputjoycheck, 80, 20);
324
    gtk_widget_add_accelerator (inputjoycheck, "grab_focus", accel_group,
325
                                GDK_J, GDK_MOD1_MASK,
326
                                GTK_ACCEL_VISIBLE);
327
 
328
    // 3D video mode combo
329
    {
330
        GtkListStore *list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
331
        GtkCellRenderer *cell;
332
 
333
        vmode3dcombo = gtk_combo_box_new_with_model (GTK_TREE_MODEL(list));
334
        g_object_unref(G_OBJECT(list));
335
 
336
        cell = gtk_cell_renderer_text_new();
337
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(vmode3dcombo), cell, FALSE);
338
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(vmode3dcombo), cell, "text", 0, NULL);
339
    }
340
    gtk_widget_show (vmode3dcombo);
341
    gtk_fixed_put (GTK_FIXED (configlayout), vmode3dcombo, 88, 0);
342
    gtk_widget_set_size_request (vmode3dcombo, 150, 29);
343
    gtk_widget_add_accelerator (vmode3dcombo, "grab_focus", accel_group,
344
                                GDK_V, GDK_MOD1_MASK,
345
                                GTK_ACCEL_VISIBLE);
346
 
347
    // Always show config checkbox
348
    alwaysshowcheck = gtk_check_button_new_with_mnemonic ("_Always show configuration on start");
349
    gtk_widget_show (alwaysshowcheck);
350
    gtk_box_pack_start (GTK_BOX (configvlayout), alwaysshowcheck, FALSE, FALSE, 0);
351
    gtk_widget_add_accelerator (alwaysshowcheck, "grab_focus", accel_group,
352
                                GDK_A, GDK_MOD1_MASK,
353
                                GTK_ACCEL_VISIBLE);
354
 
355
    // Configuration tab
356
    configtab = gtk_label_new ("Configuration");
357
    gtk_widget_show (configtab);
358
    gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 0), configtab);
359
 
360
    // Messages scrollable area
361
    messagesscroll = gtk_scrolled_window_new (NULL, NULL);
362
    gtk_widget_show (messagesscroll);
363
    gtk_container_add (GTK_CONTAINER (tabs), messagesscroll);
364
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (messagesscroll), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
365
 
366
    // Messages text area
367
    messagestext = gtk_text_view_new ();
368
    gtk_widget_show (messagestext);
369
    gtk_container_add (GTK_CONTAINER (messagesscroll), messagestext);
370
    gtk_text_view_set_editable (GTK_TEXT_VIEW (messagestext), FALSE);
371
    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (messagestext), GTK_WRAP_WORD);
372
    gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (messagestext), FALSE);
373
    gtk_text_view_set_left_margin (GTK_TEXT_VIEW (messagestext), 2);
374
    gtk_text_view_set_right_margin (GTK_TEXT_VIEW (messagestext), 2);
375
 
376
    // Messages tab
377
    messagestab = gtk_label_new ("Messages");
378
    gtk_widget_show (messagestab);
379
    gtk_notebook_set_tab_label (GTK_NOTEBOOK (tabs), gtk_notebook_get_nth_page (GTK_NOTEBOOK (tabs), 1), messagestab);
380
 
381
    // Dialogue box buttons layout
382
    buttons = gtk_hbutton_box_new ();
383
    gtk_widget_show (buttons);
384
    gtk_box_pack_start (GTK_BOX (vlayout), buttons, FALSE, TRUE, 0);
385
    gtk_container_set_border_width (GTK_CONTAINER (buttons), 3);
386
    gtk_button_box_set_layout (GTK_BUTTON_BOX (buttons), GTK_BUTTONBOX_END);
387
 
388
    // Cancel button
389
    cancelbutton = gtk_button_new ();
390
    gtk_widget_show (cancelbutton);
391
    gtk_container_add (GTK_CONTAINER (buttons), cancelbutton);
392
    GTK_WIDGET_SET_FLAGS (cancelbutton, GTK_CAN_DEFAULT);
393
    gtk_widget_add_accelerator (cancelbutton, "grab_focus", accel_group,
394
                                GDK_C, GDK_MOD1_MASK,
395
                                GTK_ACCEL_VISIBLE);
197 terminx 396
    gtk_widget_add_accelerator (cancelbutton, "clicked", accel_group,
397
                                GDK_Escape, 0,
398
                                GTK_ACCEL_VISIBLE);
194 terminx 399
 
400
    cancelbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
401
    gtk_widget_show (cancelbuttonalign);
402
    gtk_container_add (GTK_CONTAINER (cancelbutton), cancelbuttonalign);
403
 
404
    cancelbuttonlayout = gtk_hbox_new (FALSE, 2);
405
    gtk_widget_show (cancelbuttonlayout);
406
    gtk_container_add (GTK_CONTAINER (cancelbuttonalign), cancelbuttonlayout);
407
 
408
    cancelbuttonicon = gtk_image_new_from_stock ("gtk-cancel", GTK_ICON_SIZE_BUTTON);
409
    gtk_widget_show (cancelbuttonicon);
410
    gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonicon, FALSE, FALSE, 0);
411
 
412
    cancelbuttonlabel = gtk_label_new_with_mnemonic ("_Cancel");
413
    gtk_widget_show (cancelbuttonlabel);
414
    gtk_box_pack_start (GTK_BOX (cancelbuttonlayout), cancelbuttonlabel, FALSE, FALSE, 0);
415
 
416
    // Start button
417
    startbutton = gtk_button_new ();
418
    gtk_widget_show (startbutton);
419
    gtk_container_add (GTK_CONTAINER (buttons), startbutton);
420
    GTK_WIDGET_SET_FLAGS (startbutton, GTK_CAN_DEFAULT);
421
    gtk_widget_add_accelerator (startbutton, "grab_focus", accel_group,
422
                                GDK_S, GDK_MOD1_MASK,
423
                                GTK_ACCEL_VISIBLE);
197 terminx 424
    gtk_widget_add_accelerator (startbutton, "clicked", accel_group,
425
                                GDK_Return, 0,
426
                                GTK_ACCEL_VISIBLE);
194 terminx 427
 
428
    startbuttonalign = gtk_alignment_new (0.5, 0.5, 0, 0);
429
    gtk_widget_show (startbuttonalign);
430
    gtk_container_add (GTK_CONTAINER (startbutton), startbuttonalign);
431
 
432
    startbuttonlayout = gtk_hbox_new (FALSE, 2);
433
    gtk_widget_show (startbuttonlayout);
434
    gtk_container_add (GTK_CONTAINER (startbuttonalign), startbuttonlayout);
435
 
436
    startbuttonicon = gtk_image_new_from_stock ("gtk-execute", GTK_ICON_SIZE_BUTTON);
437
    gtk_widget_show (startbuttonicon);
438
    gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonicon, FALSE, FALSE, 0);
439
 
440
    startbuttonlabel = gtk_label_new_with_mnemonic ("_Start");
441
    gtk_widget_show (startbuttonlabel);
442
    gtk_box_pack_start (GTK_BOX (startbuttonlayout), startbuttonlabel, FALSE, FALSE, 0);
443
 
444
    // Wire up the signals
445
    g_signal_connect ((gpointer) startwin, "delete_event",
446
                      G_CALLBACK (on_startwin_delete_event),
447
                      NULL);
448
    g_signal_connect ((gpointer) fullscreencheck, "toggled",
449
                      G_CALLBACK (on_fullscreencheck_toggled),
450
                      NULL);
451
    g_signal_connect ((gpointer) sounddrvcombo, "changed",
452
                      G_CALLBACK (on_sounddrvcombo_changed),
453
                      NULL);
454
    g_signal_connect ((gpointer) cddrvcombo, "changed",
455
                      G_CALLBACK (on_cddrvcombo_changed),
456
                      NULL);
457
    g_signal_connect ((gpointer) inputmousecheck, "toggled",
458
                      G_CALLBACK (on_inputmousecheck_toggled),
459
                      NULL);
460
    g_signal_connect ((gpointer) inputjoycheck, "toggled",
461
                      G_CALLBACK (on_inputjoycheck_toggled),
462
                      NULL);
463
    g_signal_connect ((gpointer) vmode3dcombo, "changed",
464
                      G_CALLBACK (on_vmode3dcombo_changed),
465
                      NULL);
466
    g_signal_connect ((gpointer) alwaysshowcheck, "toggled",
467
                      G_CALLBACK (on_alwaysshowcheck_toggled),
468
                      NULL);
469
    g_signal_connect ((gpointer) cancelbutton, "clicked",
470
                      G_CALLBACK (on_cancelbutton_clicked),
471
                      NULL);
472
    g_signal_connect ((gpointer) startbutton, "clicked",
473
                      G_CALLBACK (on_startbutton_clicked),
474
                      NULL);
475
 
476
    // Associate labels with their controls
477
    gtk_label_set_mnemonic_widget (GTK_LABEL (vmode3dlabel), vmode3dcombo);
478
    gtk_label_set_mnemonic_widget (GTK_LABEL (sounddrvlabel), sounddrvcombo);
479
    gtk_label_set_mnemonic_widget (GTK_LABEL (cddrvlabel), cddrvcombo);
480
 
481
    /* Store pointers to all widgets, for use by lookup_widget(). */
482
    GLADE_HOOKUP_OBJECT_NO_REF (startwin, startwin, "startwin");
483
    GLADE_HOOKUP_OBJECT (startwin, hlayout, "hlayout");
484
    GLADE_HOOKUP_OBJECT (startwin, banner, "banner");
485
    GLADE_HOOKUP_OBJECT (startwin, vlayout, "vlayout");
486
    GLADE_HOOKUP_OBJECT (startwin, tabs, "tabs");
487
    GLADE_HOOKUP_OBJECT (startwin, configvlayout, "configvlayout");
488
    GLADE_HOOKUP_OBJECT (startwin, configlayout, "configlayout");
489
    GLADE_HOOKUP_OBJECT (startwin, fullscreencheck, "fullscreencheck");
490
    GLADE_HOOKUP_OBJECT (startwin, vmode3dlabel, "vmode3dlabel");
491
    GLADE_HOOKUP_OBJECT (startwin, inputdevlabel, "inputdevlabel");
492
    GLADE_HOOKUP_OBJECT (startwin, sounddrvlabel, "sounddrvlabel");
493
    GLADE_HOOKUP_OBJECT (startwin, cddrvlabel, "cddrvlabel");
494
    GLADE_HOOKUP_OBJECT (startwin, sounddrvcombo, "sounddrvcombo");
495
    GLADE_HOOKUP_OBJECT (startwin, cddrvcombo, "cddrvcombo");
496
    GLADE_HOOKUP_OBJECT (startwin, inputmousecheck, "inputmousecheck");
497
    GLADE_HOOKUP_OBJECT (startwin, inputjoycheck, "inputjoycheck");
498
    GLADE_HOOKUP_OBJECT (startwin, vmode3dcombo, "vmode3dcombo");
499
    GLADE_HOOKUP_OBJECT (startwin, alwaysshowcheck, "alwaysshowcheck");
500
    GLADE_HOOKUP_OBJECT (startwin, configtab, "configtab");
501
    GLADE_HOOKUP_OBJECT (startwin, messagesscroll, "messagesscroll");
502
    GLADE_HOOKUP_OBJECT (startwin, messagestext, "messagestext");
503
    GLADE_HOOKUP_OBJECT (startwin, messagestab, "messagestab");
504
    GLADE_HOOKUP_OBJECT (startwin, buttons, "buttons");
505
    GLADE_HOOKUP_OBJECT (startwin, cancelbutton, "cancelbutton");
506
    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonalign, "cancelbuttonalign");
507
    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlayout, "cancelbuttonlayout");
508
    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonicon, "cancelbuttonicon");
509
    GLADE_HOOKUP_OBJECT (startwin, cancelbuttonlabel, "cancelbuttonlabel");
510
    GLADE_HOOKUP_OBJECT (startwin, startbutton, "startbutton");
511
    GLADE_HOOKUP_OBJECT (startwin, startbuttonalign, "startbuttonalign");
512
    GLADE_HOOKUP_OBJECT (startwin, startbuttonlayout, "startbuttonlayout");
513
    GLADE_HOOKUP_OBJECT (startwin, startbuttonicon, "startbuttonicon");
514
    GLADE_HOOKUP_OBJECT (startwin, startbuttonlabel, "startbuttonlabel");
515
 
516
    gtk_window_add_accel_group (GTK_WINDOW (startwin), accel_group);
517
 
518
    return startwin;
519
}
520
 
521
// -- BUILD ENTRY POINTS ------------------------------------------------------
522
 
523
int startwin_open(void)
524
{
525
    if (!gtkenabled) return 0;
526
    if (startwin) return 1;
527
 
528
    startwin = create_window();
529
    if (startwin) {
530
        SetPage(TAB_MESSAGES);
531
        gtk_widget_show(startwin);
532
        gtk_main_iteration_do(FALSE);
533
        return 0;
534
    }
535
    return -1;
536
}
537
 
538
int startwin_close(void)
539
{
540
    if (!gtkenabled) return 0;
541
    if (!startwin) return 1;
542
    gtk_widget_destroy (startwin);
543
    startwin = NULL;
544
    return 0;
545
}
546
 
547
int startwin_puts(const char *str)
548
{
549
    GtkWidget *textview;
550
    GtkTextBuffer *textbuffer;
551
    GtkTextIter enditer;
552
    GtkTextMark *mark;
553
    const char *aptr, *bptr;
554
 
555
    if (!gtkenabled || !str) return 0;
556
    if (!startwin) return 1;
557
    if (!(textview = lookup_widget(startwin, "messagestext"))) return -1;
558
    textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
559
 
560
    gtk_text_buffer_get_end_iter(textbuffer, &enditer);
561
    for (aptr = bptr = str; *aptr != 0; ) {
562
        switch (*bptr) {
563
        case '\b':
564
            if (bptr > aptr)
565
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr)-1);
566
#if GTK_CHECK_VERSION(2,6,0)
567
            gtk_text_buffer_backspace(textbuffer, &enditer, FALSE, TRUE);
568
#else
569
            {
570
                GtkTextIter iter2 = enditer;
571
                gtk_text_iter_backward_cursor_position(&iter2);
572
                //FIXME: this seems be deleting one too many chars somewhere!
573
                if (!gtk_text_iter_equal(&iter2, &enditer))
574
                    gtk_text_buffer_delete_interactive(textbuffer, &iter2, &enditer, TRUE);
575
            }
576
#endif
577
            aptr = ++bptr;
578
            break;
579
        case 0:
580
            if (bptr > aptr)
581
                gtk_text_buffer_insert(textbuffer, &enditer, (const gchar *)aptr, (gint)(bptr-aptr));
582
            aptr = bptr;
583
            break;
584
        case '\r':      // FIXME
585
        default:
586
            bptr++;
587
            break;
588
        }
589
    }
590
 
591
    mark = gtk_text_buffer_create_mark(textbuffer, NULL, &enditer, 1);
592
    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, FALSE, 0.0, 1.0);
593
    gtk_text_buffer_delete_mark(textbuffer, mark);
594
 
595
    return 0;
596
}
597
 
598
int startwin_settitle(const char *title)
599
{
600
    if (!gtkenabled) return 0;
601
    if (!startwin) return 1;
602
    gtk_window_set_title (GTK_WINDOW (startwin), title);
603
    return 0;
604
}
605
 
606
int startwin_idle(void *s)
607
{
608
    if (!gtkenabled) return 0;
609
    //if (!startwin) return 1;
610
    gtk_main_iteration_do (FALSE);
611
    return 0;
612
}
613
 
614
extern int xdimgame, ydimgame, bppgame, forcesetup;
615
 
616
int startwin_run(void)
617
{
618
    if (!gtkenabled) return 0;
619
    if (!startwin) return 1;
620
 
621
    SetPage(TAB_CONFIG);
622
 
623
    settings.fullscreen = ScreenMode;
624
    settings.xdim3d = ScreenWidth;
625
    settings.ydim3d = ScreenHeight;
626
    settings.bpp3d = ScreenBPP;
627
    settings.forcesetup = ForceSetup;
628
    settings.usemouse = UseMouse;
629
    settings.usejoy = UseJoystick;
630
    PopulateForm();
631
 
632
    gtk_main();
633
 
634
    SetPage(TAB_MESSAGES);
635
    if (retval) {
636
        ScreenMode = settings.fullscreen;
637
        ScreenWidth = settings.xdim3d;
638
        ScreenHeight = settings.ydim3d;
639
        ScreenBPP = settings.bpp3d;
640
        ForceSetup = settings.forcesetup;
641
        UseMouse = settings.usemouse;
642
        UseJoystick = settings.usejoy;
643
    }
644
 
645
    return retval;
646
}
647