Changeset 197

Show
Ignore:
Timestamp:
06/21/07 19:00:36 (2 years ago)
Author:
takkaria
Message:

Commit the current GTK2 code (doesn't run on my machine, but I hope that can be fixed fairly soon.)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/configure.ac

    r182 r197  
    1616 
    1717test "$GCC" = "yes" && CFLAGS="$CFLAGS -Wall -pipe -g -fno-strength-reduce" 
    18 PICFLAGS="-fPIC" 
    19 AC_SUBST(PICFLAGS) 
    2018 
    2119dnl Checks for various programs 
     
    137135fi 
    138136 
    139  
    140137dnl SDL checking 
    141138if test "$enable_sdl" = "yes"; then 
     
    159156dnl GTK checking 
    160157if test "$enable_gtk" = "yes"; then 
    161         PKG_CHECK_MODULES(GTK, [glib-2.0 >= 2.6.0 gtk+-2.0 >= 2.6.0 gthread-2.0 pango], 
     158        PKG_CHECK_MODULES(GTK, [glib-2.0 >= 2.6.0 gtk+-2.0 >= 2.6.0 gthread-2.0 pango libglade], 
    162159                [with_gtk=yes], 
    163160                [with_gtk=no] 
     
    189186 
    190187dnl Check for headers, types, functions 
    191 AC_CHECK_HEADERS([fcntl.h stdint.h]) 
     188AC_CHECK_HEADERS([fcntl.h stdint.h dirent.h]) 
    192189AC_HEADER_STDBOOL 
    193190AC_C_CONST 
  • trunk/lib/pref/font.prf

    r147 r197  
    3232%:font-mac.prf 
    3333 
     34?:[EQU $SYS gtk] 
     35%:font-gtk.prf 
     36 
    3437?:[EQU $SYS win] 
    3538%:font-win.prf 
  • trunk/src/Makefile.std

    r174 r197  
    3838 
    3939# Support the GTK2 graphical tookit (main-gtk.c) 
    40 SYS_gtk = -DUSE_GTK $(shell pkg-config gtk+-2.0 --libs --cflags) 
     40SYS_gtk = -rdynamic -export-dynamic -DUSE_GTK $(shell pkg-config libglade-2.0 gtk+-2.0  --libs  --cflags)  
    4141 
    4242# Support SDL frontend 
  • trunk/src/main-gtk.c

    r155 r197  
    11/* 
    22 * File: main-gtk.c 
    3  * Purpose: Angband GTK2 port 
     3 * Purpose: GTK port for Angband 
    44 * 
    5  * Copyright (c) 2000-2007 Robert Ruehlmann, Andrew Sidwell, Shanonah Alkire 
     5 * Copyright (c) 2000-2007 Robert Ruehlmann, Shanoah Alkire 
    66 * 
    77 * This work is free software; you can redistribute it and/or modify it 
     
    2525#include <gtk/gtk.h> 
    2626#include <gdk/gdkkeysyms.h> 
    27  
    28 /* 
    29  * Include some helpful X11 code. 
    30  */ 
    31 #include "maid-x11.h" 
    32  
    33  
    34 #define NO_PADDING 0 
    35  
    36 #define MAX_TERM_DATA 8 
    37  
     27#include <glade/glade.h> 
     28 
     29#define MAX_TERM_DATA 1 
    3830/* 
    3931 * Extra data to associate with each "window" 
     
    5244        GtkWidget *window; 
    5345        GtkWidget *drawing_area; 
    54         GdkFont *font; 
     46         
     47        cairo_t *cairo_draw; 
     48        PangoFontDescription *font; 
     49        PangoLayout *layout; 
     50         
    5551        GdkPixmap *pixmap; 
    56         GdkGC *gc
     52        GdkGC *gc, *back_color
    5753 
    5854        int font_wid; 
    5955        int font_hgt; 
    60  
     56         
     57        int tile_wid; 
     58        int tile_hgt; 
     59        GdkPixmap *tiles; 
     60        GdkPixmap *mask; 
    6161        int rows; 
    6262        int cols; 
     
    7171static term_data data[MAX_TERM_DATA]; 
    7272 
    73  
    7473/* 
    7574 * game in progress 
     
    8281static int num_term = 1; 
    8382 
     83/* Our glade file */ 
     84GladeXML *xml; 
     85 
     86 
     87/* 
     88 * Path to the Gtk settings file 
     89 */ 
     90char settings[1024]; 
     91 
     92/* 
     93 * Set foreground color 
     94 */ 
     95static void set_foreground_color(term_data *td, byte a) 
     96{ 
     97        static unsigned int failed = 0; 
     98        GdkColor color; 
     99        /*int red, green, blue;*/ 
     100 
     101        color.red     = angband_color_table[a][1] * 256; 
     102        color.green = angband_color_table[a][2] * 256; 
     103        color.blue    = angband_color_table[a][3] * 256; 
     104         
     105        g_assert(td->cairo_draw != 0); 
     106 
     107        if (gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE))  
     108        { 
     109                gdk_gc_set_foreground(td->gc, &color); 
     110                cairo_set_source_rgb (td->cairo_draw, color.red, color.green, color.blue); 
     111        } 
     112        else if (!failed++) 
     113                g_print("Couldn't allocate color.\n"); 
     114} 
     115 
     116/*  
     117 * Set a GdkRectangle  
     118 */ 
     119 
     120static void init_gdk_rect(GdkRectangle *r, int x, int y, int w, int h) 
     121{ 
     122        r->x = x; 
     123        r->y = y; 
     124        r->width = w; 
     125        r->height = h; 
     126} 
     127 
     128/* 
     129 * Draw a cairo rectangle from a GdkRectangle object. 
     130 */ 
     131static void c_rect(cairo_t *cr, GdkRectangle r) 
     132{ 
     133        cairo_rectangle (cr, r.x, r.y, r.width, r.height); 
     134} 
    84135 
    85136/* 
     
    88139static errr Term_clear_gtk(void) 
    89140{ 
    90         int width, height
     141        GdkRectangle r
    91142 
    92143        term_data *td = (term_data*)(Term->data); 
    93  
     144         
     145        /* Set dimensions of the window */ 
     146        init_gdk_rect(&r, 0, 0, td->cols * td->font_wid, td->rows * td->font_hgt); 
     147         
     148        g_assert(td->drawing_area->window != 0); 
     149         
     150        /* Clear the area */ 
     151        cairo_save(td->cairo_draw); 
     152         
     153        c_rect(td->cairo_draw, r); 
     154        set_foreground_color(td, TERM_DARK); 
     155        cairo_fill(td->cairo_draw); 
     156        cairo_close_path(td->cairo_draw); 
     157 
     158        cairo_restore(td->cairo_draw); 
     159         
     160        gdk_window_invalidate_rect(td->drawing_area->window, &r, TRUE); 
     161        gdk_window_process_updates(td->drawing_area->window, TRUE); 
     162 
     163        /* Success */ 
     164        return (0); 
     165
     166 
     167 
     168/* 
     169 * Erase some characters. 
     170 */ 
     171static errr Term_wipe_gtk(int x, int y, int n) 
     172
     173        GdkRectangle r; 
     174        term_data *td = (term_data*)(Term->data); 
     175         
     176        /* Set dimensions */ 
     177        init_gdk_rect(&r, x * td->font_wid, y * td->font_hgt,  td->font_wid * n, td->font_hgt); 
     178         
    94179        g_assert(td->pixmap != NULL); 
    95180        g_assert(td->drawing_area->window != 0); 
    96  
    97         /* Find proper dimensions for rectangle */ 
    98         gdk_window_get_size(td->drawing_area->window, &width, &height); 
    99  
    100         /* Clear the area */ 
    101         gdk_draw_rectangle(td->pixmap, td->drawing_area->style->black_gc, 
    102                            1, 0, 0, width, height); 
    103  
    104         /* Copy it to the window */ 
    105         gdk_draw_pixmap(td->drawing_area->window, td->gc, td->pixmap, 
    106                         0, 0, 0, 0, width, height); 
     181         
     182        cairo_save(td->cairo_draw); 
     183         
     184        c_rect(td->cairo_draw, r); 
     185        set_foreground_color(td, TERM_DARK); 
     186        cairo_fill(td->cairo_draw); 
     187        cairo_close_path(td->cairo_draw); 
     188         
     189        cairo_restore(td->cairo_draw); 
     190         
     191        gdk_window_invalidate_rect(td->drawing_area->window, &r, TRUE); 
     192        gdk_window_process_updates(td->drawing_area->window, TRUE); 
    107193 
    108194        /* Success */ 
     
    110196} 
    111197 
    112  
    113 /* 
    114  * Erase some characters. 
    115  */ 
    116 static errr Term_wipe_gtk(int x, int y, int n) 
     198/* 
     199 * Draw some textual characters. 
     200 */ 
     201static errr Term_text_gtk(int x, int y, int n, byte a, cptr s) 
    117202{ 
    118203        term_data *td = (term_data*)(Term->data); 
    119  
    120         g_assert(td->pixmap != NULL); 
    121         g_assert(td->drawing_area->window != 0); 
    122  
    123         gdk_draw_rectangle(td->pixmap, td->drawing_area->style->black_gc, 
    124                            TRUE, x * td->font_wid, y * td->font_hgt, 
    125                            n * td->font_wid, td->font_hgt); 
    126  
    127         /* Copy it to the window */ 
    128         gdk_draw_pixmap(td->drawing_area->window, td->gc, td->pixmap, 
    129                         x * td->font_wid, y * td->font_hgt, 
    130                         x * td->font_wid, y * td->font_hgt, 
    131                         n * td->font_wid, td->font_hgt); 
    132  
     204        GdkRectangle r; 
     205         
     206        /* Set dimensions */ 
     207        init_gdk_rect(&r, x * td->font_wid, y * td->font_hgt,  td->font_wid * n, td->font_hgt); 
     208         
     209        g_assert(td->layout != NULL); 
     210         
     211        /* Clear the line */ 
     212        Term_wipe_gtk(x, y, n); 
     213         
     214        cairo_save(td->cairo_draw); 
     215         
     216        /* Create a PangoLayout, set the font and text */ 
     217        set_foreground_color(td, a); 
     218        pango_layout_set_text(td->layout, s, n); 
     219        pango_layout_set_font_description(td->layout, td->font); 
     220         
     221        /* Draw the text to the pixmap */ 
     222        cairo_move_to(td->cairo_draw, r.x, r.y); 
     223        pango_cairo_show_layout(td->cairo_draw, td->layout); 
     224         
     225        cairo_restore(td->cairo_draw); 
     226         
     227        gdk_window_invalidate_rect(td->drawing_area->window, &r, TRUE); 
     228        gdk_window_process_updates(td->drawing_area->window, TRUE); 
     229                         
    133230        /* Success */ 
    134231        return (0); 
    135232} 
    136233 
    137  
    138 /* 
    139  * Set foreground color 
    140  */ 
    141 static void set_foreground_color(term_data *td, byte a) 
    142 { 
    143         static unsigned int failed = 0; 
    144  
    145         GdkColor color; 
    146  
    147         color.red   = angband_color_table[a][1] * 256; 
    148         color.green = angband_color_table[a][2] * 256; 
    149         color.blue  = angband_color_table[a][3] * 256; 
    150  
    151         g_assert(td->pixmap != NULL); 
    152         g_assert(td->drawing_area->window != 0); 
    153  
    154         if (gdk_colormap_alloc_color(gdk_colormap_get_system(), &color, FALSE, TRUE)) 
    155                 gdk_gc_set_foreground(td->gc, &color); 
    156         else if (!failed++) 
    157                 g_print("Couldn't allocate color.\n"); 
    158 } 
    159  
    160  
    161 /* 
    162  * Draw some textual characters. 
    163  */ 
    164 static errr Term_text_gtk(int x, int y, int n, byte a, cptr s) 
    165 { 
    166         int i; 
    167         term_data *td = (term_data*)(Term->data); 
    168          
    169         set_foreground_color(td, a); 
    170  
    171         /* Clear the line */ 
    172         Term_wipe_gtk(x, y, n); 
    173  
    174         /* Draw the text to the pixmap */ 
    175         for (i = 0; i < n; i++) 
    176         { 
    177                 gdk_draw_text(td->pixmap, td->font, td->gc, 
    178                               (x + i) * td->font_wid, 
    179                               td->font->ascent + y * td->font_hgt, 
    180                               s + i, 1); 
    181         } 
    182  
    183         /* Copy it to the window */ 
    184         gdk_draw_pixmap(td->drawing_area->window, td->gc, td->pixmap, 
    185                         x * td->font_wid, y * td->font_hgt, 
    186                         x * td->font_wid, y * td->font_hgt, 
    187                         n * td->font_wid, td->font_hgt); 
    188  
    189         /* Success */ 
    190         return (0); 
    191 } 
    192  
    193  
    194234static errr CheckEvent(bool wait) 
    195235{ 
     
    210250static errr Term_flush_gtk(void) 
    211251{ 
     252        gdk_flush(); 
    212253        /* XXX */ 
    213254        return (0); 
     
    261302{ 
    262303        term_data *td = (term_data*)(Term->data); 
    263  
     304        GdkRectangle r; 
     305 
     306        /* Set dimensions */ 
     307        init_gdk_rect(&r, x * td->font_wid, y * td->font_hgt,  td->font_wid, td->font_hgt); 
     308         
     309        cairo_save(td->cairo_draw); 
     310         
     311        c_rect(td->cairo_draw, r); 
    264312        set_foreground_color(td, TERM_YELLOW); 
    265          
    266         gdk_draw_rectangle(td->pixmap, td->gc, FALSE, 
    267                            x * td->font_wid, y * td->font_hgt, td->font_wid - 1, td->font_hgt - 1); 
    268  
    269         /* Copy it to the window */ 
    270         gdk_draw_pixmap(td->drawing_area->window, td->gc, td->pixmap, 
    271                         x * td->font_wid, y * td->font_hgt, 
    272                         x * td->font_wid, y * td->font_hgt, 
    273                         td->font_wid, td->font_hgt); 
    274  
     313        cairo_stroke(td->cairo_draw); 
     314         
     315        cairo_restore(td->cairo_draw); 
     316         
     317        gdk_window_invalidate_rect(td->drawing_area->window, &r, TRUE); 
     318        gdk_window_process_updates(td->drawing_area->window, TRUE); 
     319        gdk_flush(); 
     320         
    275321        /* Success */ 
    276322        return (0); 
    277323} 
    278324 
     325/* 
     326 * Hack -- redraw a term_data 
     327 * 
     328 * Note that "Term_redraw()" calls "TERM_XTRA_CLEAR" 
     329 */ 
     330static void term_data_redraw(term_data *td) 
     331{ 
     332        term *old = Term; 
     333        /* Activate the term */ 
     334        Term_activate(&data[0].t); 
     335 
     336        /* Redraw the contents */ 
     337        Term_redraw(); 
     338 
     339        /* Flush the output */ 
     340        Term_fresh(); 
     341        Term_activate(old); 
     342} 
    279343 
    280344static void save_game_gtk(void) 
     
    290354                /* Hack -- Forget messages */ 
    291355                msg_flag = FALSE; 
    292  
     356                 
    293357                /* Save the game */ 
    294358#ifdef ZANGBAND 
     
    307371 
    308372 
    309 static void quit_event_handler(GtkButton *was_clicked, gpointer user_data) 
     373void quit_event_handler(GtkButton *was_clicked, gpointer user_data) 
    310374{ 
    311375        save_game_gtk(); 
    312  
    313376        quit(NULL); 
    314 
    315  
    316  
    317 static void destroy_event_handler(GtkButton *was_clicked, gpointer user_data) 
     377        gtk_exit(0); 
     378
     379 
     380 
     381void destroy_event_handler(GtkButton *was_clicked, gpointer user_data) 
    318382{ 
    319383        quit(NULL); 
    320 
    321  
    322  
    323 static void hide_event_handler(GtkWidget *window, gpointer user_data) 
     384        gtk_exit(0); 
     385
     386 
     387 
     388void hide_event_handler(GtkWidget *window, gpointer user_data) 
    324389{ 
    325390        gtk_widget_hide(window); 
     
    327392 
    328393 
    329 static void new_event_handler(GtkButton *was_clicked, gpointer user_data) 
     394void new_event_handler(GtkButton *was_clicked, gpointer user_data) 
    330395{ 
    331396        if (game_in_progress) 
     
    349414/*** Callbacks: font selector */ 
    350415 
    351 static void load_font(term_data *td, cptr fontname) 
    352 
    353         td->font = gdk_font_load(fontname); 
    354  
    355         /* Calculate the size of the font XXX */ 
    356         td->font_wid = gdk_char_width(td->font, '@'); 
    357         td->font_hgt = td->font->ascent + td->font->descent; 
    358 
    359  
    360 static void font_ok_callback(GtkWidget *widget, GtkWidget *font_selector) 
     416static void load_font_by_name(term_data *td, cptr fontname) 
     417{        
     418        PangoRectangle r; 
     419        PangoLayout *temp; 
     420         
     421        cairo_t *cr; 
     422        cairo_surface_t *surface; 
     423         
     424        GdkPixmap *temp_pix; 
     425         
     426        /* Create a temp pango/cairo context to play in */ 
     427        surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200); 
     428        cr = cairo_create(surface); 
     429        temp = pango_cairo_create_layout(cr); 
     430        td->font =  pango_font_description_from_string(fontname); 
     431         
     432        g_assert(surface != NULL); 
     433        g_assert(cr != NULL); 
     434        g_assert(td->font != NULL); 
     435         
     436        plog(fontname); 
     437         
     438        /* Draw an @, and measure it */ 
     439        pango_layout_set_font_description(temp, td->font); 
     440        pango_layout_set_text(temp, "@", 1); 
     441        pango_cairo_show_layout(cr, temp); 
     442        pango_layout_get_pixel_extents(temp, NULL, &r); 
     443         
     444        /* Set the char width and height */ 
     445        td->font_wid = r.width; 
     446        td->font_hgt = r.height; 
     447        plog_fmt("Width & Height: %i, %i", td->font_wid, td->font_hgt); 
     448         
     449        /* Blow up our temp variables */ 
     450        g_object_unref(temp); 
     451        cairo_destroy(cr); 
     452        cairo_surface_destroy(surface); 
     453         
     454        if (td->pixmap != NULL)  
     455        { 
     456        /* Resize the term window accordingly */ 
     457        gtk_widget_set_size_request(GTK_WIDGET(td->drawing_area), td->cols * td->font_wid + 1, td->rows * td->font_hgt + 1); 
     458        /* Hack - the values I'm giving it are smaller then the size the window should be; 
     459            and as such, it sets it to the smallest size it can while showing everything, 
     460            which is actually what I want it at. */ 
     461        gtk_window_resize(td->window, td->cols * td->font_wid + 1, td->rows * td->font_hgt + 1); 
     462         
     463                 
     464        /* Move out old pixmap, etc... to different vars */ 
     465        temp_pix = td->pixmap; 
     466        cr = td->cairo_draw; 
     467        temp = td->layout; 
     468         
     469        /* Make a new pixmap, cairo context, etc */ 
     470        td->pixmap = gdk_pixmap_new(td->drawing_area->window, td->cols * td->font_wid, td->rows * td->font_hgt, -1); 
     471        g_object_set_data(G_OBJECT(td->drawing_area), "pixmap", td->pixmap); 
     472        td->cairo_draw = gdk_cairo_create(td->pixmap); 
     473        td->layout = pango_cairo_create_layout (td->cairo_draw);  
     474         
     475        /* Destroy the old ones */ 
     476        g_object_unref(temp); 
     477        cairo_destroy(cr); 
     478        g_object_unref(temp_pix); 
     479                 
     480        Term_flush(); 
     481        term_data_redraw(td); 
     482        } 
     483        plog("Cleaned up."); 
     484
     485 
     486void font_ok_callback(GtkWidget *widget, GtkWidget *font_selector) 
    361487{ 
    362488        gchar *fontname; 
    363         term_data *td = gtk_object_get_data(GTK_OBJECT(font_selector), "term_data"); 
     489        term_data *td = g_object_get_data(G_OBJECT(font_selector), "term_data"); 
    364490 
    365491        g_assert(td != NULL); 
    366492 
    367493        fontname = gtk_font_selection_dialog_get_font_name(GTK_FONT_SELECTION_DIALOG(font_selector)); 
    368  
    369         g_assert(fontname != NULL); 
    370  
    371         load_font(td, fontname); 
    372 
    373  
    374  
    375 static void change_font_event_handler(GtkWidget *widget, gpointer user_data) 
     494         
     495        load_font_by_name(td, fontname); 
     496        g_assert(td->font != NULL); 
     497
     498 
     499 
     500void change_font_event_handler(GtkWidget *widget, gpointer user_data) 
    376501{ 
    377502        GtkWidget *font_selector; 
    378  
    379         gchar *spacings[] = { "c", "m", NULL }; 
    380  
    381         font_selector = gtk_font_selection_dialog_new("Select font"); 
    382  
    383         gtk_object_set_data(GTK_OBJECT(font_selector), "term_data", user_data); 
    384  
    385 #if 0 
    386         /* Filter to show only fixed-width fonts */ 
    387         gtk_font_selection_dialog_set_filter(GTK_FONT_SELECTION_DIALOG(font_selector), 
    388                                              GTK_FONT_FILTER_BASE, GTK_FONT_ALL, 
    389                                              NULL, NULL, NULL, NULL, spacings, NULL); 
    390 #endif 
    391  
    392         gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->ok_button), 
    393                            "clicked", font_ok_callback, (gpointer)font_selector); 
     503        GtkFontSelectionDialog *dialog; 
     504        term_data *td = (term_data*)(Term->data); 
     505        char *fontname = pango_font_description_to_string(td->font); 
     506         
     507        font_selector = glade_xml_get_widget(xml, "font-window"); 
     508         
     509        g_object_set_data(G_OBJECT(font_selector), "term_data", user_data); 
     510         
     511        dialog = GTK_FONT_SELECTION_DIALOG(font_selector); 
     512         
     513        gtk_font_selection_dialog_set_font_name(dialog, fontname); 
     514         
     515        g_signal_connect(G_OBJECT(dialog->ok_button), "clicked", G_CALLBACK(font_ok_callback),  
     516                                   (gpointer)font_selector); 
    394517 
    395518        /* Ensure that the dialog box is destroyed when the user clicks a button. */ 
    396         gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->ok_button), 
    397                                   "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), 
    398                                   (gpointer)font_selector); 
    399  
    400         gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(font_selector)->cancel_button), 
    401                                   "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), 
    402                                  (gpointer)font_selector); 
     519        g_signal_connect_swapped(G_OBJECT(dialog->ok_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_hide), 
     520                                                   (gpointer)font_selector); 
     521 
     522        g_signal_connect_swapped(G_OBJECT(dialog->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_hide), 
     523                                                  (gpointer)font_selector); 
    403524 
    404525        gtk_widget_show(GTK_WIDGET(font_selector)); 
     
    428549} 
    429550 
    430  
    431  
    432 static void open_event_handler(GtkButton *was_clicked, gpointer user_data) 
     551/* 
     552 * Open/Save Dialog box 
     553 */ 
     554static bool save_dialog_box(bool save) 
    433555{ 
    434556        GtkWidget *selector_wid; 
    435557        GtkFileChooser *selector; 
    436  
     558        bool accepted; 
     559         
    437560        char buf[1024]; 
    438561        const char *filename; 
     
    440563        /* Forget it if the game is in progress */ 
    441564        /* XXX Should disable the menu entry */ 
    442         if (game_in_progress
     565        if (game_in_progress && !save
    443566        { 
    444567                plog("You can't open a new game while you're still playing!"); 
    445                 return; 
    446         } 
    447  
     568                return FALSE; 
     569        } 
     570                         
     571        if ((!game_in_progress || !character_generated) && save) 
     572        { 
     573                plog("You can't save a new game unless you're still playing!"); 
     574                return FALSE; 
     575        } 
     576 
     577        if (!inkey_flag && save) 
     578        { 
     579                plog("You may not do that right now."); 
     580                return FALSE; 
     581        } 
     582         
    448583        /* Create a new file selector dialogue box, with no parent */ 
     584        if (!save) 
     585        { 
    449586        selector_wid = gtk_file_chooser_dialog_new("Select a savefile", NULL, 
    450587                                               GTK_FILE_CHOOSER_ACTION_OPEN, 
     
    452589                                               GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, 
    453590                                               NULL); 
    454  
     591        } 
     592        else 
     593        { 
     594        selector_wid = gtk_file_chooser_dialog_new("Save your game", NULL, 
     595                                               GTK_FILE_CHOOSER_ACTION_SAVE, 
     596                                               GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 
     597                                               GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, 
     598                                               NULL); 
     599        } 
    455600        /* For convenience */ 
    456601        selector = GTK_FILE_CHOOSER(selector_wid); 
    457  
     602        gtk_file_chooser_set_do_overwrite_confirmation (selector, TRUE); 
     603         
    458604        /* Get the current directory (so we can find lib/save/) */ 
    459605        filename = gtk_file_chooser_get_current_folder(selector); 
     
    467613        gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_DISPLAY_NAME, file_open_filter, NULL, NULL); 
    468614        gtk_file_chooser_set_filter(selector, filter); 
    469  
     615         
     616        accepted = (gtk_dialog_run(GTK_DIALOG(selector_wid)) == GTK_RESPONSE_ACCEPT); 
    470617        /* Run the dialogue */ 
    471         if (gtk_dialog_run(GTK_DIALOG(selector_wid)) == GTK_RESPONSE_ACCEPT
     618        if (accepted
    472619        { 
    473620                /* Get the filename, copy it into the savefile name */ 
    474621                filename = gtk_file_chooser_get_filename(selector); 
    475622                my_strcpy(savefile, filename, sizeof(savefile)); 
    476  
     623        } 
     624                 
     625        /* Destroy it now that we're done with it */ 
     626        gtk_widget_destroy(selector_wid); 
     627         
     628        /* Done */ 
     629        return accepted; 
     630
     631 
     632void open_event_handler(GtkButton *was_clicked, gpointer user_data) 
     633
     634        bool accepted; 
     635         
     636        accepted = save_dialog_box(FALSE); 
     637         
     638        if (accepted) 
     639        { 
    477640                /* Start playing the game */ 
    478641                game_in_progress = TRUE; 
    479642                Term_flush(); 
    480643                play_game(FALSE); 
     644#ifdef HAS_CLEANUP 
    481645                cleanup_angband(); 
     646#endif /* HAS_CLEANUP */ 
    482647                quit(NULL); 
    483648        } 
    484  
    485         /* Destroy it now we're done */ 
    486         gtk_widget_destroy(selector); 
    487  
     649         
    488650        /* Done */ 
    489651        return; 
    490652} 
    491  
    492  
    493  
    494  
    495  
    496  
    497 static gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, gpointer user_data) 
     653void save_event_handler(GtkButton *was_clicked, gpointer user_data) 
     654
     655        bool accepted; 
     656         
     657        accepted = save_dialog_box(TRUE); 
     658         
     659        if (accepted) 
     660        { 
     661                Term_flush(); 
     662                save_game_gtk(); 
     663        } 
     664         
     665        /* Done */ 
     666        return; 
     667
     668gboolean delete_event_handler(GtkWidget *widget, GdkEvent *event, gpointer user_data) 
    498669{ 
    499670        save_game_gtk(); 
    500  
    501         /* Don't prevent closure */ 
    502671        return (FALSE); 
    503672} 
    504  
    505  
    506 static gboolean keypress_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 
     673gboolean toggle_menu(GtkWidget *widget, GdkEvent *event, gpointer user_data) 
     674
     675        return(FALSE); 
     676
     677 
     678gboolean keypress_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer user_data) 
    507679{ 
    508680        int i, mc, ms, mo, mx; 
     
    577749                        return (TRUE); 
    578750                } 
    579  
    580751                case GDK_Shift_L: 
    581752                case GDK_Shift_R: 
     
    617788} 
    618789 
    619  
    620 static gboolean expose_event_handler(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 
     790gboolean expose_event_handler(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 
    621791{ 
    622792        term_data *td = user_data; 
    623  
    624         GdkPixmap *pixmap = gtk_object_get_data(GTK_OBJECT(widget), "pixmap"); 
    625  
     793         
     794        GdkPixmap *pixmap = g_object_get_data(G_OBJECT(widget), "pixmap"); 
    626795        if (pixmap) 
    627796        { 
    628                 /* Restrict the area - Don't forget to reset it! XXX */ 
    629                 /* gdk_gc_set_clip_rectangle(td->gc, &(event->area)); */ 
    630  
    631797                g_assert(widget->window != 0); 
    632  
    633                 gdk_draw_pixmap(widget->window, td->gc, pixmap, 
     798                 
     799                gdk_draw_drawable(widget->window, td->gc, pixmap, 
    634800                                event->area.x, event->area.y, 
    635801                                event->area.x, event->area.y, 
     
    640806} 
    641807 
    642  
    643808static errr term_data_init(term_data *td, int i) 
    644809{ 
     
    657822        t->soft_cursor = TRUE; 
    658823 
    659         /* Erase with "white space" */ 
    660         t->attr_blank = TERM_WHITE
     824        /* Erase with "dark space" */ 
     825        t->attr_blank = TERM_DARK
    661826        t->char_blank = ' '; 
    662827 
     
    676841} 
    677842 
    678  
    679843static void init_gtk_window(term_data *td, int i) 
    680844{ 
    681845        cptr font; 
    682  
     846        char buf[1024]; 
     847         
    683848        bool main_window = (i == 0) ? TRUE : FALSE; 
    684  
    685         GtkWidget *menu_bar, *file_item, *file_menu, *box; 
    686         GtkWidget *seperator_item, *file_exit_item, *file_new_item, *file_open_item; 
    687         GtkWidget *options_item, *options_menu, *options_font_item; 
    688  
    689         /* Get default font for this term */ 
    690         font = get_default_font(i); 
    691  
    692         load_font(td, font); 
    693  
    694         /* Create widgets */ 
    695         td->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
    696         box = gtk_vbox_new(FALSE, 0); 
    697         td->drawing_area = gtk_drawing_area_new(); 
    698  
     849        GtkWidget *menu_item; 
     850 
     851        /* Default to the default monospace font in Gtk */ 
     852        font = "Monospace 12"; 
     853        load_font_by_name(td, font); 
     854         
     855        /* Build the path */ 
     856        path_build(buf, sizeof(buf), ANGBAND_DIR_XTRA, "angband.glade"); 
     857         
     858        plog_fmt("ANGBAND_XTRA path = %s",buf); 
     859         
     860        /* Set up the Glade file */ 
     861        xml = glade_xml_new(buf, NULL); 
     862         
     863        if (main_window) 
     864        { 
     865                td->window = glade_xml_get_widget(xml, "main-window"); 
     866                td->drawing_area = glade_xml_get_widget(xml, "drawingarea1"); 
     867                menu_item = glade_xml_get_widget(xml, "font_menu_item"); 
     868                g_signal_connect (menu_item, "activate", G_CALLBACK(change_font_event_handler), td); 
     869                 
     870        } 
     871        else 
     872        { 
     873                td->window = glade_xml_get_widget(xml, "term-window"); 
     874                td->drawing_area = glade_xml_get_widget(xml, "drawingarea2"); 
     875                g_signal_connect(td->window, "hide_event", G_CALLBACK(hide_event_handler), td); 
     876        } 
     877         
     878        g_signal_connect(td->drawing_area, "expose_event", G_CALLBACK(expose_event_handler), td); 
     879         
     880        g_assert(td->window != NULL); 
     881        g_assert(td->drawing_area != NULL); 
     882         
     883        /* connect signal handlers that aren't passed data */ 
     884        glade_xml_signal_autoconnect(xml); 
     885         
    699886        /* Set attributes */ 
    700887        gtk_window_set_title(GTK_WINDOW(td->window), td->name); 
    701         gtk_drawing_area_size(GTK_DRAWING_AREA(td->drawing_area), td->cols * td->font_wid, td->rows * td->font_hgt); 
    702  
    703         gtk_signal_connect(GTK_OBJECT(td->window), "delete_event", GTK_SIGNAL_FUNC(delete_event_handler), NULL); 
    704         gtk_signal_connect(GTK_OBJECT(td->window), "key_press_event", GTK_SIGNAL_FUNC(keypress_event_handler), NULL); 
    705         gtk_signal_connect(GTK_OBJECT(td->drawing_area), "expose_event", GTK_SIGNAL_FUNC(expose_event_handler), td); 
    706  
    707         if (main_window) 
    708                 gtk_signal_connect(GTK_OBJECT(td->window), "destroy_event", GTK_SIGNAL_FUNC(destroy_event_handler), NULL); 
    709         else 
    710                 gtk_signal_connect(GTK_OBJECT(td->window), "destroy_event", GTK_SIGNAL_FUNC(hide_event_handler), td); 
    711  
    712         gtk_container_add(GTK_CONTAINER(td->window), box); 
    713  
    714         /* Create main-menu */ 
    715         if (main_window) 
    716         { 
    717                 /* Create the menu-bar and menu-items */ 
    718                 menu_bar = gtk_menu_bar_new(); 
    719                 file_item = gtk_menu_item_new_with_label("File"); 
    720                 file_menu = gtk_menu_new(); 
    721                 file_new_item = gtk_menu_item_new_with_label("New"); 
    722                 file_open_item = gtk_menu_item_new_with_label("Open"); 
    723                 seperator_item = gtk_menu_item_new(); 
    724                 file_exit_item = gtk_menu_item_new_with_label("Exit"); 
    725                 options_item = gtk_menu_item_new_with_label("Options"); 
    726                 options_menu = gtk_menu_new(); 
    727                 options_font_item = gtk_menu_item_new_with_label("Font"); 
    728  
    729                 /* Register callbacks */ 
    730                 g_signal_connect(GTK_OBJECT(file_exit_item), "activate", G_CALLBACK(quit_event_handler), NULL); 
    731                 g_signal_connect(GTK_OBJECT(file_new_item), "activate", G_CALLBACK(new_event_handler), NULL); 
    732                 g_signal_connect(GTK_OBJECT(file_open_item), "activate", G_CALLBACK(open_event_handler), NULL); 
    733                 g_signal_connect(GTK_OBJECT(options_font_item), "activate", G_CALLBACK(change_font_event_handler), td); 
    734  
    735                 /* Build the menu bar */ 
    736                 gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), file_item); 
    737                 gtk_menu_bar_append(GTK_MENU_BAR(menu_bar), options_item); 
    738                 gtk_menu_item_set_submenu(GTK_MENU_ITEM(file_item), file_menu); 
    739                 gtk_menu_item_set_submenu(GTK_MENU_ITEM(options_item), options_menu); 
    740                 gtk_menu_append(GTK_MENU(file_menu), file_new_item); 
    741                 gtk_menu_append(GTK_MENU(file_menu), file_open_item); 
    742                 gtk_menu_append(GTK_MENU(file_menu), seperator_item); 
    743                 gtk_menu_append(GTK_MENU(file_menu), file_exit_item); 
    744                 gtk_menu_append(GTK_MENU(options_menu), options_font_item); 
    745  
    746                 /* Pack the menu bar */ 
    747                 gtk_box_pack_start(GTK_BOX(box), menu_bar, FALSE, FALSE, NO_PADDING); 
    748         } 
    749  
    750         /* Pack the display area */ 
    751         gtk_box_pack_start_defaults(GTK_BOX(box), td->drawing_area); 
    752  
     888        gtk_widget_set_size_request(GTK_WIDGET(td->drawing_area), td->cols * td->font_wid + 1, td->rows * td->font_hgt + 1); 
     889        gtk_window_move( GTK_WINDOW(td->window), 100, 100); 
     890 
     891        /* Create a pixmap as buffer for screen updates */ 
     892        td->pixmap = gdk_pixmap_new(td->drawing_area->window, td->cols * td->font_wid, td->rows * td->font_hgt, -1); 
     893        g_object_set_data(G_OBJECT(td->drawing_area), "pixmap", td->pixmap); 
     894        td->gc = gdk_gc_new(td->drawing_area->window); 
     895        td->cairo_draw = gdk_cairo_create(td->pixmap); 
     896        td->layout = pango_cairo_create_layout (td->cairo_draw);  
     897         
     898        g_assert(td->pixmap != NULL); 
     899        g_assert(td->gc != NULL); 
     900        g_assert(td->cairo_draw != NULL); 
     901        g_assert(td->layout != NULL); 
     902         
    753903        /* Show the widgets */ 
    754904        gtk_widget_show_all(td->window); 
    755  
    756         /* Create a pixmap as buffer for screenupdates */ 
    757         td->pixmap = gdk_pixmap_new(td->drawing_area->window, td->cols * td->font_wid, td->rows * td->font_hgt, -1); 
    758         gtk_object_set_data(GTK_OBJECT(td->drawing_area), "pixmap", td->pixmap); 
    759         td->gc = gdk_gc_new(td->drawing_area->window); 
    760  
    761         /* Clear the pixmap */ 
    762         gdk_draw_rectangle(td->pixmap, td->drawing_area->style->black_gc, TRUE, 
    763                            0, 0, 
    764                            td->cols * td->font_wid, td->rows * td->font_hgt); 
    765  
    766         /* Copy it to the window */ 
    767         gdk_draw_pixmap(td->drawing_area->window, td->gc, td->pixmap, 
    768                         0, 0, 0, 0, 
    769                         td->cols * td->font_wid, td->rows * td->font_hgt); 
    770905} 
    771906 
     
    784919        /* Initialize the environment */ 
    785920        gtk_init(&argc, &argv); 
    786  
     921         
    787922        /* Parse args */ 
    788923        for (i = 1; i < argc; i++) 
     
    798933                plog_fmt("Ignoring option: %s", argv[i]); 
    799934        } 
    800  
     935         
    801936        /* Initialize the windows */ 
    802937        for (i = 0; i < num_term; i++)