Subversion Repositories eduke32

Rev

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