~ubuntu-branches/ubuntu/natty/gtkboard/natty

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.11pre0+cvs.2003.11.02-2/src/menu.c

  • Committer: Bazaar Package Importer
  • Author(s): Barak A. Pearlmutter
  • Date: 2011-02-28 11:25:02 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20110228112502-e9aah248wxelm7ao
Tags: 0.11pre0+cvs.2003.11.02-2
autotools tweaks, most notably -lSDL to supplement -lSDL_mixer

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is a part of gtkboard, a board games system.
 
2
    Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
 
17
 
 
18
*/
 
19
#include <string.h>
 
20
#include <assert.h>
 
21
#include <stdlib.h>
 
22
 
 
23
#include "config.h"
 
24
#include "ui.h"
 
25
#include "menu.h"
 
26
#include "move.h"
 
27
#include "ui_common.h"
 
28
#include "aaball.h"
 
29
#include "board.h"
 
30
#include "prefs.h"
 
31
#include "sound.h"
 
32
 
 
33
#ifdef HAVE_GNOME
 
34
#include "libgnome/libgnome.h"
 
35
#include "libgnomeui/libgnomeui.h"
 
36
#include "../pixmaps/logo48.xpm"
 
37
#endif
 
38
 
 
39
GtkWidget *sb_message_label, *sb_game_label, *sb_score_label,
 
40
        *sb_who_label, *sb_player_label, *sb_time_label, *sb_turn_image,
 
41
        *menu_main, *menu_info_bar, *menu_info_separator, *menu_warning_bar;
 
42
GtkWidget *sb_game_separator, *sb_who_separator, *sb_score_separator,
 
43
        *sb_player_separator, *sb_time_separator, *sb_turn_separator,
 
44
        *sb_warning_separator;
 
45
#define SB_MESSAGE_STRLEN 64
 
46
gchar sb_message_str[SB_MESSAGE_STRLEN] = "";
 
47
#define SB_SCORE_STRLEN 32
 
48
gchar sb_score_str[SB_SCORE_STRLEN] = "";
 
49
GtkItemFactory *menu_factory = NULL;
 
50
 
 
51
void sb_messagebar_message (gchar *);
 
52
void menu_cleanup_var_menus ();
 
53
 
 
54
static char * menu_paths_sens_machine_thinking[] = 
 
55
{
 
56
//      "/File/Load game",
 
57
//      "/File/Save game",
 
58
        "/Game/Start",
 
59
        "/Game/New",
 
60
        "/Game/Select Game",
 
61
        "/Settings",
 
62
        "/Move/Back",
 
63
        "/Move/Forward",
 
64
};
 
65
 
 
66
static char * menu_paths_sens_no_game[] = 
 
67
{
 
68
        "/Game/Start",
 
69
        "/Game/Pause",
 
70
        "/Game/New",
 
71
        "/Game/Highscores",
 
72
        "/Game/Zap Highscores",
 
73
//      "/File/Save game",
 
74
        "/Move/Back",
 
75
        "/Move/Forward",
 
76
        "/Settings/Flip Board",
 
77
        "/Settings/Player",
 
78
};
 
79
 
 
80
static char * menu_paths_sens_no_back_forw[] = 
 
81
{
 
82
        "/Move/Back",
 
83
        "/Move/Forward",
 
84
};
 
85
 
 
86
static char *menu_paths_sens_single_player[] =
 
87
{
 
88
        "/Settings/Player",
 
89
        "/Settings/Flip Board",
 
90
//      "/Settings/Eval function",
 
91
};
 
92
 
 
93
static char *menu_paths_sens_two_players[] =
 
94
{
 
95
        "/Game/Highscores",
 
96
        "/Game/Zap Highscores",
 
97
};
 
98
 
 
99
static char *menu_paths_sens_ui_stopped[] = 
 
100
{
 
101
        "/Game/Pause",
 
102
};
 
103
 
 
104
static char *menu_paths_sens_machine_not_thinking[] = 
 
105
{
 
106
        "/Move/Move Now",
 
107
};
 
108
 
 
109
static char *menu_paths_sens_eval_function[] = 
 
110
{
 
111
//      "/Settings/Eval function",
 
112
};
 
113
 
 
114
void sb_set_score (gchar *score)
 
115
{
 
116
        strncpy (sb_score_str, score, SB_SCORE_STRLEN-1);
 
117
        sb_update ();
 
118
}
 
119
 
 
120
void menu_sensitize (int which, gboolean sens)
 
121
{
 
122
        int i, num_paths = -1;
 
123
        char **menu_des_paths = NULL;
 
124
        if (!state_gui_active) return;
 
125
        switch (which)
 
126
        {
 
127
                case MENU_SENS_MACHINE_THINKING: 
 
128
                        menu_des_paths = menu_paths_sens_machine_thinking;
 
129
                        num_paths = sizeof (menu_paths_sens_machine_thinking) / 
 
130
                                sizeof (menu_paths_sens_machine_thinking[0]);
 
131
                        break;
 
132
                case MENU_SENS_MACHINE_NOT_THINKING: 
 
133
                        menu_des_paths = menu_paths_sens_machine_not_thinking;
 
134
                        num_paths = sizeof (menu_paths_sens_machine_not_thinking) / 
 
135
                                sizeof (menu_paths_sens_machine_not_thinking[0]);
 
136
                        break;
 
137
                case MENU_SENS_NO_GAME: 
 
138
                        menu_des_paths = menu_paths_sens_no_game;
 
139
                        num_paths = sizeof (menu_paths_sens_no_game) / 
 
140
                                sizeof (menu_paths_sens_no_game[0]);
 
141
                        break;
 
142
                case MENU_SENS_NO_BACK_FORW: 
 
143
                        menu_des_paths = menu_paths_sens_no_back_forw;
 
144
                        num_paths = sizeof (menu_paths_sens_no_back_forw) / 
 
145
                                sizeof (menu_paths_sens_no_back_forw[0]);
 
146
                        break;
 
147
                case MENU_SENS_SINGLE_PLAYER: 
 
148
                        menu_des_paths = menu_paths_sens_single_player;
 
149
                        num_paths = sizeof (menu_paths_sens_single_player) / 
 
150
                                sizeof (menu_paths_sens_single_player[0]);
 
151
                        break;
 
152
                case MENU_SENS_TWO_PLAYERS: 
 
153
                        menu_des_paths = menu_paths_sens_two_players;
 
154
                        num_paths = sizeof (menu_paths_sens_two_players) / 
 
155
                                sizeof (menu_paths_sens_two_players[0]);
 
156
                        break;
 
157
                case MENU_SENS_UI_STOPPED: 
 
158
                        menu_des_paths = menu_paths_sens_ui_stopped;
 
159
                        num_paths = sizeof (menu_paths_sens_ui_stopped) / 
 
160
                                sizeof (menu_paths_sens_ui_stopped[0]);
 
161
                        break;
 
162
                case MENU_SENS_EVAL_FUNCTION:
 
163
                        menu_des_paths = menu_paths_sens_eval_function;
 
164
                        num_paths = sizeof (menu_paths_sens_eval_function) / 
 
165
                                sizeof (menu_paths_sens_eval_function[0]);
 
166
                        break;
 
167
                default:
 
168
                        g_assert_not_reached ();
 
169
        }
 
170
        for (i=0; i<num_paths; i++)
 
171
                gtk_widget_set_sensitive (gtk_item_factory_get_widget (menu_factory, 
 
172
                                        menu_des_paths[i]), sens);
 
173
}
 
174
 
 
175
void sb_set_turn_image ()
 
176
{
 
177
#if GTK_MAJOR_VERSION == 2
 
178
        // FIXME: can't get existing bgcolor
 
179
        const int size = 20;
 
180
        static char pixbufs [7][size*(size+1)];
 
181
        char **pixmap_data;
 
182
        static GdkPixmap *pixmaps[7];
 
183
        int colors[7] = {0x007700, 0x77ff77, 0x770000, 0xff7777, 0x000077, 0x7777ff,
 
184
                                        0x777777};
 
185
        int i, j;
 
186
        static int first = 1;
 
187
        static int previndex = -1;
 
188
        int index = -1;
 
189
        if (first)
 
190
        {
 
191
                int i;
 
192
                for (i=0; i<7; i++)
 
193
                {
 
194
                        pixmap_data = pixmap_ball_gen (size, pixbufs[i], colors[i], 
 
195
                                        0xffffff, 6.5, 24);
 
196
                        pixmaps[i] = gdk_pixmap_create_from_xpm_d 
 
197
                                ((GdkWindow *)main_window->window, NULL, NULL, pixmap_data);
 
198
                }
 
199
                gtk_image_set_from_pixmap (GTK_IMAGE (sb_turn_image), 
 
200
                                pixmaps[previndex = 6], NULL);
 
201
                first = 0;
 
202
        }
 
203
        if (opt_infile || !opt_game)
 
204
                index = 6;
 
205
        else 
 
206
        {
 
207
                if (!game_single_player && ui_white == HUMAN && ui_black == HUMAN
 
208
                                && cur_pos.player == BLACK) index = 4;
 
209
                else index =  (player_to_play == HUMAN ? 0 : 2);
 
210
                if (ui_stopped) index++;
 
211
        }
 
212
        g_assert (index >= 0 && index <= 6);
 
213
        if (index == previndex) return;
 
214
        gtk_image_set_from_pixmap (GTK_IMAGE (sb_turn_image), 
 
215
                        pixmaps[previndex = index], NULL);
 
216
#endif
 
217
}
 
218
 
 
219
static void sb_set_cursor ()
 
220
{
 
221
        static GdkCursor *cursor_normal = NULL, *cursor_busy = NULL, 
 
222
                *cursor_inactive = NULL;
 
223
        // FIXME: is it ok to hard code the shape of the normal cursor?
 
224
        if (!cursor_normal) cursor_normal = gdk_cursor_new (GDK_LEFT_PTR);
 
225
        if (!cursor_busy) cursor_busy = gdk_cursor_new (GDK_WATCH);
 
226
        if (!cursor_inactive) cursor_inactive = gdk_cursor_new (GDK_XTERM);
 
227
        if (player_to_play == MACHINE && !ui_stopped)
 
228
                gdk_window_set_cursor (board_area->window, cursor_busy);
 
229
        else if (player_to_play == MACHINE && ui_stopped)
 
230
                gdk_window_set_cursor (board_area->window, cursor_inactive);
 
231
        else
 
232
                gdk_window_set_cursor (board_area->window, cursor_normal);
 
233
}
 
234
 
 
235
void menu_board_flip_cb ()
 
236
{
 
237
        if (game_single_player)
 
238
        {
 
239
                sb_error ("Can't flip board in single player game", TRUE);
 
240
                return;
 
241
        }
 
242
        if (!game_allow_flip)
 
243
        {
 
244
                sb_error ("This game doesn't allow the board to be flipped", TRUE);
 
245
                return;
 
246
        }
 
247
        state_board_flipped = state_board_flipped ? FALSE : TRUE;
 
248
        board_redraw (NULL, NULL);
 
249
}
 
250
 
 
251
 
 
252
static void menu_show_dialog_real (gchar *title, gchar *message, gboolean wrap)
 
253
        // A modal dialog with a label. Don't use it for showing large amounts of text
 
254
{
 
255
        GtkWidget *dialog, *okay_button, *label;
 
256
 
 
257
#if GTK_MAJOR_VERSION == 1
 
258
        label = gtk_label_new (message);
 
259
        dialog = gtk_dialog_new();
 
260
        gtk_window_set_title (GTK_WINDOW (dialog), title);
 
261
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
 
262
        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 
263
        okay_button = gtk_button_new_with_label("OK");
 
264
 
 
265
        gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
 
266
                        GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
 
267
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
 
268
                        okay_button);
 
269
#else
 
270
        label = gtk_label_new (NULL);
 
271
        gtk_label_set_markup (GTK_LABEL (label), message);
 
272
        dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (main_window),
 
273
                        GTK_DIALOG_MODAL, NULL);
 
274
        gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 100);
 
275
        okay_button = gtk_dialog_add_button (GTK_DIALOG (dialog), 
 
276
                        GTK_STOCK_OK, GTK_RESPONSE_NONE);
 
277
        g_signal_connect_swapped (GTK_OBJECT (dialog), 
 
278
                        "response", G_CALLBACK (gtk_widget_destroy), GTK_OBJECT (dialog));
 
279
        gtk_label_set_selectable (GTK_LABEL (label), TRUE);
 
280
#endif
 
281
        gtk_label_set_line_wrap (GTK_LABEL (label), wrap);
 
282
        gtk_widget_grab_focus (okay_button);
 
283
 
 
284
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
 
285
        gtk_widget_show_all (dialog);
 
286
}
 
287
 
 
288
void menu_show_dialog (gchar *title, gchar *message)
 
289
{
 
290
        menu_show_dialog_real (title, message, FALSE);
 
291
}
 
292
 
 
293
void menu_show_dialog_wrap (gchar *title, gchar *message)
 
294
{
 
295
        menu_show_dialog_real (title, message, TRUE);
 
296
}
 
297
        
 
298
 
 
299
void menu_pause_cb (GtkWidget *dialog)
 
300
{
 
301
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
302
        menu_start_stop_game (NULL, MENU_START_GAME);
 
303
}
 
304
 
 
305
void menu_show_pause_dialog ()
 
306
        // Game paused
 
307
{
 
308
        GtkWidget *dialog, *okay_button, *label;
 
309
        gchar *title = "Game paused - gtkboard";
 
310
        gchar *msg = "Game paused. Click OK to continue";
 
311
 
 
312
        board_hide();
 
313
 
 
314
        label = gtk_label_new (msg);
 
315
#if GTK_MAJOR_VERSION == 1
 
316
        dialog = gtk_dialog_new();
 
317
        gtk_window_set_title (GTK_WINDOW (dialog), title);
 
318
        gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
 
319
        gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
 
320
        okay_button = gtk_button_new_with_label("OK");
 
321
 
 
322
        gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
 
323
                        GTK_SIGNAL_FUNC (menu_pause_cb), (gpointer) dialog);
 
324
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
 
325
                        okay_button);
 
326
        gtk_widget_grab_focus (okay_button);
 
327
 
 
328
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
 
329
        gtk_widget_show_all (dialog);
 
330
#else
 
331
        dialog = gtk_message_dialog_new (GTK_WINDOW (main_window), 
 
332
                        GTK_DIALOG_MODAL,
 
333
                        GTK_MESSAGE_INFO,
 
334
                        GTK_BUTTONS_OK,
 
335
                        msg);
 
336
/*      dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW (main_window),
 
337
                        GTK_DIALOG_MODAL, NULL);
 
338
        gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 100);
 
339
        okay_button = gtk_dialog_add_button (GTK_DIALOG (dialog), 
 
340
                        GTK_STOCK_OK, GTK_RESPONSE_NONE);
 
341
        gtk_label_set_selectable (GTK_LABEL (label), TRUE);
 
342
*/
 
343
#endif
 
344
 
 
345
#if GTK_MAJOR_VERSION > 1
 
346
        gtk_dialog_run (GTK_DIALOG (dialog));
 
347
        menu_pause_cb (dialog);
 
348
#endif
 
349
}
 
350
 
 
351
void menu_show_about_dialog (gpointer data)
 
352
{
 
353
#ifdef HAVE_GNOME
 
354
        GtkWidget *about;
 
355
        GdkPixmap *logo_pixmap;
 
356
        GdkPixbuf *logo_pixbuf;
 
357
        const gchar *authors[] = {"Arvind Narayanan <arvindn@users.sourceforge.net>", "Ron Hale-Evans <rwhe@ludism.org>", NULL};
 
358
        gchar *logo_filename;
 
359
        logo_filename = g_strdup_printf ("%s/pixmaps/gtkboard.png", DATADIR);
 
360
        logo_pixbuf = gdk_pixbuf_new_from_file (logo_filename, NULL);
 
361
        if (!logo_pixbuf)
 
362
        {
 
363
                fprintf (stderr, "Warning: couldn't load icon from file %s\n", logo_filename);
 
364
                logo_pixmap = gdk_pixmap_create_from_xpm_d (main_window->window, NULL, NULL, logo48_xpm);
 
365
                logo_pixbuf = gdk_pixbuf_get_from_drawable (NULL, logo_pixmap, 
 
366
                                gdk_colormap_get_system (), 0, 0, 0, 0, -1, -1);
 
367
                gdk_pixmap_unref (logo_pixmap);
 
368
        }
 
369
        g_free (logo_filename);
 
370
        about = gnome_about_new (PACKAGE, VERSION, 
 
371
                        "Copyright (C) 2003 Arvind Narayanan",
 
372
                        NULL, authors, NULL, NULL, logo_pixbuf);
 
373
        gtk_widget_show (about);
 
374
#else
 
375
        menu_show_dialog ("About gtkboard", 
 
376
                        "gtkboard " VERSION "\n"
 
377
                        "http://gtkboard.sourceforge.net/\n"
 
378
                        "Maintainer: Arvind Narayanan <arvindn@users.sourceforge.net>\n"
 
379
                        "Released under the GNU General Public License\n"
 
380
                        "See the file COPYING for details\n"
 
381
                        "\n"
 
382
                        "The documentation is available in the doc/ directory\n"
 
383
                        "of the source distribution or in the directory\n" 
 
384
                        "/usr/local/doc/gtkboard-" VERSION "/ if you installed from binary rpm.\n"
 
385
                        "The latest documentation will always be available at\n"
 
386
                        "http://gtkboard.sourceforge.net/doc/"
 
387
                        );
 
388
#endif
 
389
}
 
390
 
 
391
void menu_show_begging_dialog (gpointer data)
 
392
{
 
393
        menu_show_dialog_wrap ("Begging bowl",
 
394
                        "Thanks for using gtkboard. I hope you liked it.\n\n"
 
395
                        "The download counter on sourceforge is broken. "
 
396
                        "They call it an \"inaccuracy\", but the fact of the matter is that it's firmly stuck at zero, which means that I have no idea how many people are downloading/using the software. So you see, I'm as lonely as a lark (or whatever it is that's supposed to be very lonely.) So if you have any comments or suggestions, or even just some kind words, it would be nice if you can mail them me. My email is arvindn@users.sourceforge.net. Thanks."
 
397
                        );
 
398
}
 
399
 
 
400
void menu_help_home_page (gpointer data)
 
401
{
 
402
#ifdef HAVE_GNOME
 
403
        if (!gnome_url_show ("http://gtkboard.sourceforge.net/", NULL))
 
404
                sb_error ("Couldn't launch home page", TRUE);
 
405
#else
 
406
        fprintf (stderr, "warning: menu_show_home_page() called even though gnome integration not compiled in\n");
 
407
#endif
 
408
}
 
409
 
 
410
 
 
411
        
 
412
void menu_put_player ();
 
413
 
 
414
void menu_start_stop_game (gpointer data, guint what)
 
415
{
 
416
        switch (what)
 
417
        {
 
418
                case MENU_START_GAME:
 
419
                        if (!opt_game) break;
 
420
                        if (!ui_stopped)
 
421
                                break;
 
422
                        board_show();
 
423
                        if (ui_gameover)
 
424
                        {
 
425
                                sb_error ("Game over", FALSE);
 
426
                                break;
 
427
                        }
 
428
                        if (!impl_check()) 
 
429
                        {       
 
430
                                sb_error ("Not yet implemented", TRUE);
 
431
                                break;
 
432
                        }
 
433
                        ui_stopped = FALSE;
 
434
                        ui_send_make_move ();
 
435
                        sb_update();
 
436
                        break;
 
437
                case MENU_STOP_GAME:
 
438
                        if (!opt_game) break;
 
439
                        if (ui_stopped) break;
 
440
                        ui_stopped = TRUE;
 
441
                        ui_cancel_move ();
 
442
                        sb_update();
 
443
                        if (game_single_player && ui_white == HUMAN)
 
444
                                menu_show_pause_dialog ();
 
445
                        break;
 
446
                case MENU_RESET_GAME:
 
447
                        {
 
448
                        int saved_white = ui_white;
 
449
                        int saved_black = ui_black;
 
450
                        if (!opt_game) break;
 
451
                        ui_terminate_game ();
 
452
                        ui_start_game ();
 
453
                        ui_white = saved_white;
 
454
                        ui_black = saved_black;
 
455
                        menu_put_player(FALSE);
 
456
                        sb_reset_human_time ();
 
457
                        ui_stopped = FALSE;
 
458
                        ui_send_make_move ();
 
459
                        sb_update();
 
460
                        break;
 
461
                        }
 
462
                default:
 
463
                        printf ("menu_start_stop_game: %d\n", what);
 
464
                        assert (0);
 
465
        }
 
466
}
 
467
 
 
468
 
 
469
// set the menu corresponding to ui_white and ui_black
 
470
// if first is TRUE use opt_white and opt_black
 
471
void menu_put_player (gboolean first)
 
472
{
 
473
        gchar *path, *paths[4] = { 
 
474
                "/Settings/Player/Human-Human", "/Settings/Player/Human-Machine",
 
475
                "/Settings/Player/Machine-Human", "/Settings/Player/Machine-Machine"};
 
476
        if (!state_gui_active) return;
 
477
        if (first) {ui_white = opt_white; ui_black = opt_black;}
 
478
        if (opt_infile)
 
479
        {
 
480
                gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM 
 
481
                (gtk_item_factory_get_widget (menu_factory, "/Settings/Player/File")), 
 
482
                              TRUE);
 
483
                        
 
484
                return;
 
485
        }       
 
486
        else if (ui_white == HUMAN && ui_black == HUMAN)
 
487
                path = paths[0];
 
488
        else if (ui_white == HUMAN && ui_black == MACHINE)
 
489
                path = paths[1];
 
490
        else if (ui_white == MACHINE && ui_black == HUMAN)
 
491
                path = paths[2];
 
492
        else if (ui_white == MACHINE && ui_black == MACHINE)
 
493
                path = paths[3];
 
494
        else
 
495
                return;
 
496
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM 
 
497
                        (gtk_item_factory_get_widget (menu_factory, path)), TRUE);
 
498
}
 
499
 
 
500
void menu_put_game ()
 
501
{
 
502
        gchar path[128] = "/Game/Select Game/";
 
503
        if (opt_game->group)
 
504
        {
 
505
                // FIXME: don't use strcat
 
506
                strncat (path, opt_game->group, 128);
 
507
                strncat (path, "/", 128);
 
508
        }
 
509
        strncat (path, opt_game->name, 128);
 
510
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM 
 
511
                        (gtk_item_factory_get_widget (menu_factory, path)), TRUE);
 
512
}
 
513
 
 
514
GtkWidget *menu_selector;
 
515
        
 
516
void menu_load_file (GtkFileSelection *selector, gpointer user_data) 
 
517
{
 
518
        gchar const *filename;
 
519
        static FILE *in;
 
520
        filename = gtk_file_selection_get_filename 
 
521
                (GTK_FILE_SELECTION(menu_selector));
 
522
        if (!(in = fopen (filename, "r")))
 
523
        {
 
524
                gchar *tempstr = g_strdup_printf 
 
525
                        ("Could not open file \"%s\" for reading", filename);
 
526
                sb_error (tempstr, TRUE);
 
527
                g_free (tempstr);
 
528
                return;
 
529
        }
 
530
        if (opt_infile)
 
531
                fclose (opt_infile);
 
532
        opt_infile = in;
 
533
        // FIXME: shouldn't this be MACHINE ?
 
534
        ui_white = ui_black = NONE;
 
535
        menu_put_player (FALSE);
 
536
        cur_pos.player = WHITE;
 
537
        game_set_init_pos (&cur_pos);
 
538
        board_redraw_all ();
 
539
        sb_message ("Opened file", FALSE);
 
540
}
 
541
 
 
542
void menu_set_player (gpointer *data, guint what, GtkWidget *widget)
 
543
{
 
544
        /* the callback for a radio button appears to
 
545
           be called TWICE, once when selected and once when something else
 
546
           is selected. */
 
547
        
 
548
        if (!GTK_CHECK_MENU_ITEM(widget)->active)
 
549
                return;
 
550
 
 
551
        if (what >= 1 && what <= 4)
 
552
                if (opt_infile)
 
553
                {
 
554
                        fclose (opt_infile);
 
555
                        opt_infile = NULL;
 
556
                }
 
557
 
 
558
        ui_stopped = TRUE;
 
559
 
 
560
        switch (what)
 
561
        {
 
562
                case 1:
 
563
                        ui_white = HUMAN;
 
564
                        ui_black = HUMAN;
 
565
                        break;
 
566
                case 2:
 
567
                        ui_white = HUMAN;
 
568
                        ui_black = MACHINE;
 
569
                        break;
 
570
                case 3:
 
571
                        ui_white = MACHINE;
 
572
                        ui_black = HUMAN;
 
573
                        break;
 
574
                case 4:
 
575
                        ui_white = MACHINE;
 
576
                        ui_black = MACHINE;
 
577
                        break;
 
578
 
 
579
                default:
 
580
                        ui_white = NONE;
 
581
                        ui_black = NONE;
 
582
                        break;
 
583
        }
 
584
 
 
585
        sb_update ();
 
586
}
 
587
 
 
588
void menu_save_file_dialog ()
 
589
{
 
590
        sb_error ("Not yet implemented", TRUE);
 
591
}
 
592
 
 
593
void menu_load_file_dialog ()
 
594
{
 
595
        if (game_single_player)
 
596
        {
 
597
                sb_error ("Can't load from file for single player game.", FALSE);
 
598
                return;
 
599
        }
 
600
        menu_selector = gtk_file_selection_new ("");
 
601
        g_assert (menu_selector);
 
602
        /*gtk_file_selection_complete (
 
603
                        GTK_FILE_SELECTION (menu_selector), "*.cbgf");*/
 
604
        
 
605
        gtk_signal_connect (GTK_OBJECT 
 
606
                (GTK_FILE_SELECTION(menu_selector)->ok_button),
 
607
                "clicked", GTK_SIGNAL_FUNC (menu_load_file), NULL);
 
608
                           
 
609
        gtk_signal_connect_object (GTK_OBJECT 
 
610
                (GTK_FILE_SELECTION(menu_selector)->ok_button),
 
611
                "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
 
612
                (gpointer) menu_selector);
 
613
 
 
614
        gtk_signal_connect_object (
 
615
                GTK_OBJECT (GTK_FILE_SELECTION(menu_selector)->cancel_button),
 
616
                "clicked", GTK_SIGNAL_FUNC (gtk_widget_destroy),
 
617
                (gpointer) menu_selector);
 
618
   
 
619
   gtk_widget_show (menu_selector);
 
620
}
 
621
 
 
622
void menu_show_game_doc (gpointer data, guint which)
 
623
{
 
624
        GtkWidget *dialog, *msgarea, *okay_button, *vbar, *hbox, *scrwin;
 
625
        char *impl;
 
626
        char *msgstr = "Nothing available"; // default
 
627
        char titlestr[64];
 
628
        switch (which)
 
629
        {
 
630
                case MENU_DOC_ABOUT:
 
631
                        switch (game_doc_about_status)
 
632
                        {
 
633
                                case STATUS_NONE: impl = ""; break;
 
634
                                case STATUS_UNPLAYABLE: impl = "Partially implemented (unplayable)"; break;
 
635
                                case STATUS_PARTIAL: impl = "Partially implemented (playable)"; break;
 
636
                                case STATUS_COMPLETE: impl = "Fully implemented"; break;
 
637
                                default: assert (0);
 
638
                        }
 
639
                        snprintf (titlestr, 64, "About %s - gtkboard", menu_get_game_name());
 
640
#if GTK_MAJOR_VERSION > 1
 
641
                        msgstr = g_strdup_printf ("<big><b>%s</b></big> <i>%s</i>\n<b>Status:</b> %s\n<b>URL:</b> <tt>http://gtkboard.sourceforge.net/games/%s</tt>",
 
642
#else
 
643
                        msgstr = g_strdup_printf ("%s -- %s\nStatus: %s\nURL: http://gtkboard.sourceforge.net/games/%s",
 
644
#endif
 
645
                                        opt_game->name,
 
646
                                        game_single_player ? "Single player game" : "Two player game",
 
647
                                        impl, 
 
648
                                        opt_game->name
 
649
                                        );
 
650
                        menu_show_dialog (titlestr, msgstr);
 
651
                        g_free (msgstr);
 
652
                        return;
 
653
                case MENU_DOC_RULES:
 
654
                        snprintf (titlestr, 64, "%s rules - gtkboard", menu_get_game_name());
 
655
                        if (game_doc_rules) msgstr = game_doc_rules;
 
656
                        break;
 
657
                case MENU_DOC_STRATEGY:
 
658
                        snprintf (titlestr, 64, "%s strategy - gtkboard", menu_get_game_name());
 
659
                        if (game_doc_strategy) msgstr = game_doc_strategy;
 
660
                        break;
 
661
                case MENU_DOC_HISTORY:
 
662
                        snprintf (titlestr, 64, "%s history - gtkboard", menu_get_game_name());
 
663
                        if (game_doc_history) msgstr = game_doc_history;
 
664
                        break;
 
665
                default:
 
666
                        assert (0);
 
667
        }
 
668
 
 
669
        vbar = gtk_vscrollbar_new(NULL);
 
670
#if GTK_MAJOR_VERSION == 1
 
671
        dialog = gtk_dialog_new();
 
672
        gtk_window_set_title (GTK_WINDOW (dialog), titlestr);
 
673
        hbox = gtk_hbox_new (FALSE, 0);
 
674
        msgarea = gtk_text_new (NULL, 
 
675
                        gtk_range_get_adjustment (GTK_RANGE (vbar)));
 
676
        gtk_text_set_word_wrap (GTK_TEXT (msgarea), TRUE);
 
677
        gtk_text_insert (GTK_TEXT (msgarea), NULL, NULL, NULL, msgstr, -1);
 
678
        gtk_box_pack_start (GTK_BOX (hbox), msgarea, TRUE, TRUE, 10);
 
679
        gtk_box_pack_start (GTK_BOX (hbox), vbar, FALSE, FALSE, 0);
 
680
        okay_button = gtk_button_new_with_label("  OK  ");
 
681
        gtk_signal_connect_object (GTK_OBJECT (okay_button), "clicked",
 
682
                        GTK_SIGNAL_FUNC (gtk_widget_destroy), (gpointer) dialog);
 
683
        gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), 
 
684
                        okay_button, FALSE, FALSE, 0);
 
685
        gtk_widget_grab_focus (okay_button);    // contributed by Paddu
 
686
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), hbox);
 
687
 
 
688
#else
 
689
        dialog = gtk_dialog_new_with_buttons (titlestr, GTK_WINDOW (main_window),
 
690
                        0, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL);
 
691
        gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300);
 
692
        g_signal_connect_swapped (GTK_OBJECT (dialog),
 
693
                        "response", G_CALLBACK (gtk_widget_destroy),
 
694
                        GTK_OBJECT (dialog));
 
695
        msgarea = gtk_text_view_new ();
 
696
        gtk_text_view_set_editable (GTK_TEXT_VIEW (msgarea), FALSE);
 
697
        gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (msgarea), GTK_WRAP_WORD);
 
698
        gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (msgarea), FALSE);
 
699
        gtk_text_buffer_set_text (gtk_text_view_get_buffer 
 
700
                        (GTK_TEXT_VIEW (msgarea)), msgstr, -1);
 
701
        scrwin = gtk_scrolled_window_new (NULL,
 
702
                gtk_range_get_adjustment (GTK_RANGE(vbar)));
 
703
        gtk_container_add (GTK_CONTAINER (scrwin), msgarea);
 
704
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), scrwin);
 
705
#endif
 
706
        gtk_widget_show_all (dialog);
 
707
}
 
708
 
 
709
void menu_put_level (char *level_name)
 
710
{
 
711
        gchar path[128] = "/Game/Levels/";
 
712
        strcat (path, level_name);
 
713
        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM 
 
714
                        (gtk_item_factory_get_widget (menu_factory, path)), TRUE);
 
715
}
 
716
 
 
717
gchar *menu_get_game_name ()
 
718
{
 
719
        if (game_levels) return game_levels[0].game->name;
 
720
        else return opt_game->name;
 
721
}
 
722
 
 
723
gchar *menu_get_game_name_with_level ()
 
724
{
 
725
        static gchar name[128];
 
726
        if (game_levels)
 
727
        {
 
728
                gchar *tempstr;
 
729
                GameLevel *level = game_levels;
 
730
                while (level->game != opt_game) { assert (level->name); level++; }
 
731
                tempstr = g_strdup_printf ("%s (%s)", 
 
732
                                game_levels[0].game->name, level->name);
 
733
                strncpy (name, tempstr, 127);
 
734
                return name;
 
735
        }
 
736
        else return opt_game->name;
 
737
}
 
738
 
 
739
void menu_set_level (gpointer data, guint which, GtkWidget *widget)
 
740
{
 
741
        Game *old_game;
 
742
        if (!GTK_CHECK_MENU_ITEM(widget)->active)
 
743
                return;
 
744
        if (!state_gui_active)
 
745
                return;
 
746
        assert (game_levels);
 
747
        old_game = game_levels[which].game;
 
748
        ui_terminate_game ();
 
749
        opt_game = old_game;
 
750
        gtk_label_set_text (GTK_LABEL (sb_game_label), 
 
751
                        menu_get_game_name_with_level ());
 
752
        ui_start_game();
 
753
}
 
754
 
 
755
GtkWidget *menu_recent_widgets[NUM_RECENT_GAMES] = {NULL};
 
756
 
 
757
 
 
758
static void menu_recent_game_cb (GtkWidget *widget, gpointer gamename)
 
759
{
 
760
        int i;
 
761
        gchar *name = gamename;
 
762
        Game *old_game = opt_game;
 
763
        for (i=0; i<num_games; i++)
 
764
        {
 
765
                if (!strcasecmp (games[i]->name, name))
 
766
                {
 
767
                        menu_cleanup_var_menus ();
 
768
                        if (opt_game)
 
769
                                ui_terminate_game ();
 
770
                        opt_game = games[i];
 
771
                        if (old_game == opt_game) menu_start_game ();
 
772
                        else menu_put_game ();
 
773
                }
 
774
        }
 
775
}
 
776
 
 
777
void menu_insert_game_item (gchar *gamename, int position)
 
778
{
 
779
        GtkWidget * child;
 
780
        GtkMenu *game_menu;
 
781
        int offset = 1; // number of menu entries before start of recent items
 
782
        game_menu = (GtkMenu *) gtk_item_factory_get_widget (menu_factory, "/Game");
 
783
        assert (game_menu);
 
784
        child = gtk_menu_item_new_with_label (gamename);
 
785
        gtk_menu_shell_insert (GTK_MENU_SHELL (game_menu), child, position - 1 + offset);
 
786
        gtk_widget_show(GTK_WIDGET (child));
 
787
        menu_recent_widgets [position-1] = child;
 
788
        gtk_signal_connect (GTK_OBJECT (child), "activate", GTK_SIGNAL_FUNC (menu_recent_game_cb), (gpointer) gamename);
 
789
}
 
790
 
 
791
void menu_insert_recent_game (gchar *gamename)
 
792
{
 
793
        int i, j;
 
794
        gchar *tmp;
 
795
        gchar *tmpname;
 
796
        for (i=0; i<NUM_RECENT_GAMES; i++)
 
797
        {
 
798
                tmpname = prefs_get_config_val (tmp = g_strdup_printf ("recent_game_%d", i+1));
 
799
                g_free (tmp);
 
800
                if (!tmpname) break;
 
801
                if (!strcasecmp (gamename, tmpname))
 
802
                        break;
 
803
        }
 
804
        
 
805
        if (tmpname)
 
806
        {
 
807
                GtkWidget *wid;
 
808
                gtk_widget_destroy (menu_recent_widgets[i == NUM_RECENT_GAMES ? i - 1 : i]);
 
809
                menu_recent_widgets[i] = NULL;
 
810
                gtk_item_factory_delete_item (menu_factory, tmp = g_strdup_printf ("/Game/%s", tmpname));
 
811
                g_free (tmp);
 
812
        }
 
813
        
 
814
        for (j=i; j>0; j--)
 
815
        {
 
816
                if (j == NUM_RECENT_GAMES) continue;
 
817
                tmpname = prefs_get_config_val (tmp = g_strdup_printf ("recent_game_%d", j));
 
818
                g_free (tmp);
 
819
                prefs_set_config_val (tmp = g_strdup_printf ("recent_game_%d", j+1), tmpname);
 
820
                menu_recent_widgets [j] = menu_recent_widgets[j-1];
 
821
        }
 
822
        prefs_set_config_val ("recent_game_1",  gamename);
 
823
 
 
824
        menu_insert_game_item (gamename, 1);
 
825
}
 
826
 
 
827
void menu_start_game ()
 
828
{
 
829
        ui_start_game ();
 
830
        
 
831
        {
 
832
        int i;
 
833
        GtkItemFactoryEntry help_items [3];
 
834
        help_items[0].path = g_strdup_printf ("/Help/%s", opt_game->name);
 
835
        help_items[0].accelerator = NULL;
 
836
        help_items[0].callback = NULL;
 
837
        help_items[0].item_type = "<Branch>";
 
838
        gtk_item_factory_create_item (menu_factory, help_items, NULL, 1);
 
839
        
 
840
        help_items[0].path = g_strdup_printf ("/Help/%s/_About", opt_game->name); 
 
841
        help_items[0].callback_action = MENU_DOC_ABOUT;
 
842
        help_items[1].path = g_strdup_printf ("/Help/%s/_Rules", opt_game->name); 
 
843
        help_items[1].callback_action = MENU_DOC_RULES;
 
844
        help_items[2].path = g_strdup_printf ("/Help/%s/_Strategy", opt_game->name); 
 
845
        help_items[2].callback_action = MENU_DOC_STRATEGY;
 
846
        help_items[3].path = g_strdup_printf ("/Help/%s/_History", opt_game->name); 
 
847
        help_items[3].callback_action = MENU_DOC_HISTORY;
 
848
        for (i=0; i<4; i++)
 
849
        {
 
850
                help_items[i].accelerator = NULL;
 
851
                help_items[i].callback = menu_show_game_doc;
 
852
                help_items[i].item_type = "";
 
853
        }
 
854
        gtk_item_factory_create_items (menu_factory, 
 
855
                        4, help_items, NULL);
 
856
        }
 
857
        
 
858
        gtk_label_set_text (GTK_LABEL (sb_game_label), 
 
859
                        menu_get_game_name_with_level());
 
860
 
 
861
        if (game_levels)
 
862
        {
 
863
                int cnt, i;
 
864
                GtkItemFactoryEntry *level_items, level_item;
 
865
                for (cnt = 0; game_levels[cnt].name; cnt++)
 
866
                        ;
 
867
                level_items = g_new0 (GtkItemFactoryEntry, cnt);
 
868
 
 
869
/*              level_item.path = "/Game/Levels";
 
870
                level_item.accelerator = NULL;
 
871
                level_item.callback = NULL;
 
872
                level_item.item_type = "<Branch>";
 
873
                gtk_item_factory_create_item (menu_factory, &level_item, NULL, 1);
 
874
*/              
 
875
                gtk_widget_show (gtk_item_factory_get_item (menu_factory,
 
876
                        "/Game/Levels"));
 
877
                        
 
878
                for (i=0; i<cnt; i++)
 
879
                {
 
880
                        level_items[i].path = g_strdup_printf ("/Game/Levels/%s",
 
881
                                        game_levels[i].name);
 
882
                        level_items[i].callback_action = i;
 
883
                        level_items[i].accelerator = NULL;
 
884
                        level_items[i].callback = menu_set_level;
 
885
                        level_items[i].item_type = i == 0 ? "<RadioItem>":  
 
886
                                g_strdup_printf ("/Game/Levels/%s", game_levels[0].name);
 
887
                        // FIXME: possible memory leak here
 
888
                }
 
889
                gtk_item_factory_create_items (menu_factory, 
 
890
                                cnt, level_items, NULL);
 
891
        }
 
892
 
 
893
        menu_insert_recent_game (menu_get_game_name ());
 
894
}
 
895
 
 
896
void menu_cleanup_var_menus ()
 
897
{
 
898
        gchar *tempstr;
 
899
        
 
900
        if (opt_game)
 
901
        {
 
902
                gchar *name = menu_get_game_name();
 
903
                // FIXME: do we need to delete recursively?
 
904
                gtk_item_factory_delete_item (menu_factory, 
 
905
                                tempstr = g_strdup_printf ("/Help/%s", name));
 
906
                g_free (tempstr);
 
907
        }
 
908
 
 
909
        if (game_levels)
 
910
        {
 
911
                gchar *tmp;
 
912
                int i;
 
913
                for (i = 0; game_levels[i].name; i++)
 
914
                {
 
915
                        gtk_item_factory_delete_item (menu_factory, 
 
916
                                        tmp = g_strdup_printf ("/Game/Levels/%s", game_levels[i].name));
 
917
                        g_free (tmp);
 
918
                }
 
919
                gtk_widget_hide (gtk_item_factory_get_widget (menu_factory, "/Game/Levels"));
 
920
        }
 
921
}
 
922
 
 
923
void menu_set_game (gpointer data, guint which, GtkWidget *widget)
 
924
{
 
925
        if (!GTK_CHECK_MENU_ITEM(widget)->active)
 
926
                return;
 
927
        if (!state_gui_active)
 
928
                return;
 
929
        g_assert (which >= 0 && which < num_games);
 
930
        
 
931
        menu_cleanup_var_menus ();
 
932
        if (opt_game)
 
933
                ui_terminate_game ();
 
934
        opt_game = games[which];
 
935
        menu_start_game ();
 
936
        sb_update ();
 
937
}
 
938
 
 
939
 
 
940
void menu_set_delay_cb (gpointer data, guint delay, GtkWidget *widget)
 
941
{
 
942
        if (!GTK_CHECK_MENU_ITEM(widget)->active)
 
943
                return;
 
944
        if (move_fout)
 
945
        {
 
946
                fprintf (move_fout, "MSEC_PER_MOVE %d\n", opt_delay = delay);
 
947
                fflush (move_fout);
 
948
        }
 
949
}
 
950
 
 
951
 
 
952
void menu_back_forw (gpointer data, guint what)
 
953
{
 
954
        byte *move;
 
955
        switch (what)
 
956
        {
 
957
                case MENU_BACK:
 
958
                        if (!game_allow_back_forw) break;
 
959
                        if (!opt_game) break;
 
960
                        if (!game_allow_undo)
 
961
                                ui_stopped = TRUE;
 
962
                        if (move_fout)
 
963
                        {
 
964
                                fprintf (move_fout, "BACK_MOVE \n");
 
965
                                fflush (move_fout);
 
966
                        }
 
967
                        move = move_fread_ack (move_fin);
 
968
                        if (!move)
 
969
                        {
 
970
                                sb_error ("Initial position. Can't go back.", FALSE);
 
971
                                break;
 
972
                        }
 
973
                        board_apply_refresh (move, NULL);
 
974
                        if (!game_single_player)
 
975
                                cur_pos.player = (cur_pos.player == WHITE ? BLACK : WHITE);
 
976
                        cur_pos.num_moves --;
 
977
                        if (game_single_player && !game_allow_undo)
 
978
                        {
 
979
                                if (!ui_cheated && game_scorecmp)
 
980
                                        sb_message ("You cheated! No highscore for this game.", FALSE);
 
981
                                ui_cheated = TRUE;
 
982
                        }
 
983
                        // FIXME: there should be only one round of communication 
 
984
                        // in which client gets both the move and who_won
 
985
                        ui_check_who_won ();
 
986
                        if (game_reset_uistate) game_reset_uistate();
 
987
                        sb_update ();
 
988
                        break;
 
989
                case MENU_FORW:
 
990
                        if (!game_allow_back_forw) break;
 
991
                        if (!opt_game) break;
 
992
                        if (move_fout)
 
993
                        {
 
994
                                fprintf (move_fout, "FORW_MOVE \n");
 
995
                                fflush (move_fout);
 
996
                        }
 
997
                        move = move_fread_ack (move_fin);
 
998
                        if (!move)
 
999
                        {
 
1000
                                sb_error ("Final position. Can't go forward.", FALSE);
 
1001
                                break;
 
1002
                        }
 
1003
                        board_apply_refresh (move, NULL);
 
1004
                        if (!game_single_player)
 
1005
                                cur_pos.player = (cur_pos.player == WHITE ? BLACK : WHITE);
 
1006
                        cur_pos.num_moves ++;
 
1007
                        ui_check_who_won ();
 
1008
                        if (game_reset_uistate) game_reset_uistate();
 
1009
                        sb_update ();
 
1010
                        break;
 
1011
                default:
 
1012
                        assert (0);
 
1013
        }
 
1014
}
 
1015
 
 
1016
//! This function is no longer used. Eval function should be set only from the command line.
 
1017
void menu_set_eval_function ()
 
1018
{
 
1019
        int i;
 
1020
        GtkWidget *menu, *menuitem;
 
1021
        GtkItemFactoryEntry heur_item;
 
1022
        static HeurTab *oldtab = NULL;
 
1023
        char *colors[2], **color, pathbuf[64];
 
1024
        return;
 
1025
        colors[0] = game_white_string;
 
1026
        colors[1] = game_black_string;
 
1027
        for (color = colors; color <= colors+1; color++)
 
1028
        {
 
1029
                if (oldtab)
 
1030
                for (i=0; oldtab[i].name; i++)
 
1031
                {
 
1032
                        char *path = g_strdup_printf ("/Settings/Eval function/%s/%s",
 
1033
                                *color, oldtab[i].name);
 
1034
                        gtk_item_factory_delete_item (menu_factory, path);
 
1035
                        g_free (path);
 
1036
                }
 
1037
                if (game_htab)
 
1038
                for (i=0; game_htab[i].name; i++)
 
1039
                {
 
1040
                        heur_item.path = g_strdup_printf ("/Settings/Eval function/%s/%s", 
 
1041
                                        *color, game_htab[i].name);
 
1042
                        if (i == 0) strncpy (pathbuf, heur_item.path, 63);
 
1043
                        heur_item.accelerator = NULL;
 
1044
                        heur_item.callback = NULL;
 
1045
                        heur_item.callback_action = 0;
 
1046
                        heur_item.item_type = (i == 0 ? "<RadioItem>" : pathbuf);
 
1047
                        gtk_item_factory_create_item (menu_factory, &heur_item, NULL, 1);
 
1048
                        g_free (heur_item.path);
 
1049
                }
 
1050
        }
 
1051
        oldtab = game_htab;
 
1052
}
 
1053
 
 
1054
void menu_enable_sound_cb (gpointer data, guint what)
 
1055
{
 
1056
        sound_set_enabled (what == 0 ? FALSE : TRUE);
 
1057
        sb_update ();
 
1058
}
 
1059
 
 
1060
void sb_message_dialog_show (char *msg, gboolean error)
 
1061
{
 
1062
        GtkWidget *dialog;
 
1063
#if GTK_MAJOR_VERSION > 1
 
1064
        dialog = gtk_message_dialog_new (GTK_WINDOW (main_window), 
 
1065
                        GTK_DIALOG_MODAL,
 
1066
                        error ? GTK_MESSAGE_ERROR : GTK_MESSAGE_INFO,
 
1067
                        GTK_BUTTONS_OK,
 
1068
                        "%s", msg);
 
1069
        gtk_dialog_run (GTK_DIALOG (dialog));
 
1070
        gtk_widget_destroy (dialog);            
 
1071
#else
 
1072
        menu_show_dialog ("Error - gtkboard", msg);
 
1073
#endif
 
1074
}       
 
1075
void sb_error (char *msg, gboolean serious)
 
1076
{
 
1077
        if (!state_gui_active)
 
1078
        {
 
1079
                fprintf (stderr, "Fatal error: %s\n", msg);
 
1080
                exit (2);
 
1081
        }
 
1082
        if (serious)
 
1083
                //menu_show_dialog ("Error - gtkboard", msg);
 
1084
                sb_message_dialog_show (msg, TRUE);
 
1085
        else
 
1086
                sb_messagebar_message (msg);
 
1087
}
 
1088
 
 
1089
void sb_message (char *msg, gboolean serious)
 
1090
{
 
1091
        if (!state_gui_active)
 
1092
                fprintf (stderr, "%s\n", msg);
 
1093
        else
 
1094
        {
 
1095
                if (serious)
 
1096
                        //sb_error (msg, serious);
 
1097
                        sb_message_dialog_show (msg, FALSE);
 
1098
                else
 
1099
                        sb_messagebar_message (msg);
 
1100
        }
 
1101
}
 
1102
 
 
1103
gchar *sb_ftime(int temps)
 
1104
{
 
1105
        static gchar ftime[10] = "  :  : ";
 
1106
        ftime[6] = temps % 10 + '0';
 
1107
        temps /= 10;
 
1108
        ftime[4] = temps % 10 + '0';
 
1109
        temps /= 10;
 
1110
        ftime[3] = temps % 6 + '0';
 
1111
        temps /= 6;
 
1112
        ftime[1] = temps % 10 + '0';
 
1113
        temps /= 10;
 
1114
        ftime[0] = temps % 6 + '0';
 
1115
        temps /= 6;
 
1116
        return ftime;
 
1117
}
 
1118
 
 
1119
static int sb_human_time = 0;
 
1120
 
 
1121
void sb_reset_human_time ()
 
1122
{
 
1123
        gchar *tempstr;
 
1124
        sb_human_time = 0;
 
1125
        if (!state_gui_active)
 
1126
                return;
 
1127
        gtk_label_set_text (GTK_LABEL(sb_time_label), tempstr
 
1128
                         = g_strdup_printf ("Time:%s", sb_ftime(sb_human_time)));
 
1129
        g_free (tempstr);
 
1130
}
 
1131
 
 
1132
int sb_get_human_time ()
 
1133
{
 
1134
        return sb_human_time;
 
1135
}
 
1136
 
 
1137
static int sb_last_msg_time = -1;
 
1138
 
 
1139
void sb_messagebar_message (gchar *msg)
 
1140
{
 
1141
        sb_last_msg_time = 0;
 
1142
        strncpy (sb_message_str, msg, SB_MESSAGE_STRLEN-1);
 
1143
        sb_update ();
 
1144
}
 
1145
 
 
1146
void menu_update ()
 
1147
        // first call all the sens and then all the desens
 
1148
{
 
1149
        // FIXME: isn't there a more elegant way to do this?
 
1150
        gboolean machine_thinking, machine_not_thinking,
 
1151
                no_game, single_player, two_players,
 
1152
                no_back_forw, eval_fn;
 
1153
        machine_thinking = (!ui_stopped && player_to_play == MACHINE);
 
1154
        machine_not_thinking = !machine_thinking;
 
1155
        no_game = opt_game ? FALSE : TRUE;
 
1156
        single_player = game_single_player;
 
1157
        two_players = !single_player;
 
1158
        no_back_forw = !game_allow_back_forw;
 
1159
        eval_fn = game_htab ? FALSE : TRUE;
 
1160
 
 
1161
        if (!machine_thinking) menu_sensitize (MENU_SENS_MACHINE_THINKING, TRUE);
 
1162
        if (!machine_not_thinking) menu_sensitize (MENU_SENS_MACHINE_NOT_THINKING, TRUE);
 
1163
        if (!no_game) menu_sensitize (MENU_SENS_NO_GAME, TRUE);
 
1164
        if (!single_player) menu_sensitize (MENU_SENS_SINGLE_PLAYER, TRUE);
 
1165
        if (!two_players) menu_sensitize (MENU_SENS_TWO_PLAYERS, TRUE);
 
1166
        if (!no_back_forw) menu_sensitize (MENU_SENS_NO_BACK_FORW, TRUE);
 
1167
        if (!ui_stopped) menu_sensitize (MENU_SENS_UI_STOPPED, TRUE);
 
1168
        if (!eval_fn) menu_sensitize (MENU_SENS_EVAL_FUNCTION, TRUE);
 
1169
 
 
1170
        if (machine_thinking) menu_sensitize (MENU_SENS_MACHINE_THINKING, FALSE);
 
1171
        if (machine_not_thinking) menu_sensitize (MENU_SENS_MACHINE_NOT_THINKING, FALSE);
 
1172
        if (no_game) menu_sensitize (MENU_SENS_NO_GAME, FALSE);
 
1173
        if (single_player) menu_sensitize (MENU_SENS_SINGLE_PLAYER, FALSE);
 
1174
        if (two_players) menu_sensitize (MENU_SENS_TWO_PLAYERS, FALSE);
 
1175
        if (no_back_forw) menu_sensitize (MENU_SENS_NO_BACK_FORW, FALSE);
 
1176
        if (ui_stopped) menu_sensitize (MENU_SENS_UI_STOPPED, FALSE);
 
1177
        if (eval_fn) menu_sensitize (MENU_SENS_EVAL_FUNCTION, FALSE);
 
1178
 
 
1179
        // TODO: express this in data rather than code
 
1180
        if (ui_stopped) 
 
1181
        {
 
1182
                gtk_widget_show (gtk_item_factory_get_widget (menu_factory,
 
1183
                        "/Game/Start"));
 
1184
                gtk_widget_hide (gtk_item_factory_get_widget (menu_factory,
 
1185
                        "/Game/Pause"));
 
1186
        }
 
1187
        else
 
1188
        {
 
1189
                gtk_widget_hide (gtk_item_factory_get_widget (menu_factory,
 
1190
                        "/Game/Start"));
 
1191
                gtk_widget_show (gtk_item_factory_get_widget (menu_factory,
 
1192
                        "/Game/Pause"));
 
1193
        }
 
1194
 
 
1195
        if (sound_get_enabled ())
 
1196
        {
 
1197
                gtk_widget_show (gtk_item_factory_get_widget (menu_factory,
 
1198
                                        "/Settings/Disable Sound"));
 
1199
                gtk_widget_hide (gtk_item_factory_get_widget (menu_factory,
 
1200
                                        "/Settings/Enable Sound"));
 
1201
        }
 
1202
        else
 
1203
        {
 
1204
                gtk_widget_hide (gtk_item_factory_get_widget (menu_factory,
 
1205
                                        "/Settings/Disable Sound"));
 
1206
                gtk_widget_show (gtk_item_factory_get_widget (menu_factory,
 
1207
                                        "/Settings/Enable Sound"));
 
1208
        }
 
1209
 
 
1210
        if (no_game)
 
1211
        {
 
1212
                gtk_widget_hide (menu_info_bar);
 
1213
                gtk_widget_hide (menu_info_separator);
 
1214
        }
 
1215
        else
 
1216
        {
 
1217
                gtk_widget_show (menu_info_bar);
 
1218
                gtk_widget_show (menu_info_separator);
 
1219
        }
 
1220
        if (game_levels)
 
1221
                gtk_widget_show (gtk_item_factory_get_item (menu_factory, "/Game/Levels"));
 
1222
        else
 
1223
                gtk_widget_hide (gtk_item_factory_get_item (menu_factory, "/Game/Levels"));
 
1224
        if (game_doc_about_status == STATUS_COMPLETE || game_doc_about_status == STATUS_NONE)
 
1225
        {
 
1226
                gtk_widget_hide (menu_warning_bar);
 
1227
                gtk_widget_hide (sb_warning_separator);
 
1228
        }
 
1229
        else
 
1230
        {
 
1231
                gtk_widget_show (menu_warning_bar);
 
1232
                gtk_widget_show (sb_warning_separator);
 
1233
        }
 
1234
        
 
1235
}
 
1236
        
 
1237
//! NOTE: sb_update() is idempotent. When in doubt, call sb_update().
 
1238
void sb_update ()
 
1239
{
 
1240
        char player[5] = "?/?";
 
1241
        if (!state_gui_active) return;
 
1242
        menu_update ();
 
1243
        if (game_single_player)
 
1244
        {
 
1245
                gtk_widget_hide (sb_player_label);
 
1246
                gtk_widget_hide (sb_who_label);
 
1247
                gtk_widget_hide (sb_player_separator);
 
1248
                gtk_widget_hide (sb_who_separator);
 
1249
                gtk_widget_show (sb_time_separator);
 
1250
                gtk_widget_show (sb_time_label);
 
1251
        }
 
1252
        else
 
1253
        {
 
1254
                gtk_widget_show (sb_player_label);
 
1255
                gtk_widget_show (sb_who_label);
 
1256
                gtk_widget_show (sb_player_separator);
 
1257
                gtk_widget_show (sb_who_separator);
 
1258
                gtk_widget_hide (sb_time_separator);
 
1259
                gtk_widget_hide (sb_time_label);
 
1260
                if (ui_white == HUMAN) player[0] = 'H';
 
1261
                if (ui_white == MACHINE) player[0] = 'M';
 
1262
                if (ui_black == HUMAN) player[2] = 'H';
 
1263
                if (ui_black == MACHINE) player[2] = 'M';
 
1264
                gtk_label_set_text (GTK_LABEL(sb_player_label), 
 
1265
                                ui_white != NONE ? player : "File");
 
1266
                gtk_label_set_text (GTK_LABEL(sb_who_label), cur_pos.player == WHITE ? 
 
1267
                                game_white_string : game_black_string);
 
1268
        }
 
1269
        gtk_label_set_text (GTK_LABEL(sb_score_label), sb_score_str);
 
1270
        sb_set_turn_image();
 
1271
        sb_set_cursor ();
 
1272
}
 
1273
 
 
1274
gboolean sb_update_periodic ()
 
1275
{
 
1276
        static gboolean first = TRUE;
 
1277
        if (!state_gui_active) return TRUE;
 
1278
        if (sb_message_str[0] != '\0' && sb_last_msg_time < 0)
 
1279
                sb_last_msg_time = 0;
 
1280
        if (sb_message_str[0] == '\0') sb_last_msg_time = -1;
 
1281
        if (sb_last_msg_time >= 0) sb_last_msg_time++;
 
1282
        if (sb_last_msg_time >= 30)
 
1283
                sb_message_str[0] = '\0';
 
1284
        gtk_label_set_text (GTK_LABEL(sb_message_label), sb_message_str);
 
1285
        {
 
1286
        gchar *tempstr = NULL;
 
1287
        if (!ui_stopped && (player_to_play == HUMAN || game_single_player))
 
1288
                gtk_label_set_text (GTK_LABEL(sb_time_label),
 
1289
                         tempstr = g_strdup_printf ("Time:%s", sb_ftime(sb_human_time++)));
 
1290
        if (first)
 
1291
                gtk_label_set_text (GTK_LABEL(sb_time_label),
 
1292
                         tempstr = g_strdup_printf ("Time:%s", sb_ftime(sb_human_time)));
 
1293
        if (tempstr) g_free (tempstr);
 
1294
        }
 
1295
        first = FALSE;
 
1296
        return TRUE;
 
1297
}