GtkWidget *area;
GtkWidget *statusbar;
GtkWidget *menubar;
+#if GTK_CHECK_VERSION(3,20,0)
+ GtkCssProvider *css_provider;
+#endif
guint statusctx;
int w, h;
midend *me;
static void set_window_background(frontend *fe, int colour)
{
-#if GTK_CHECK_VERSION(3,0,0)
+#if GTK_CHECK_VERSION(3,20,0)
+ char css_buf[512];
+ sprintf(css_buf, ".background { "
+ "background-color: #%02x%02x%02x; }",
+ (unsigned)(fe->colours[3*colour + 0] * 255),
+ (unsigned)(fe->colours[3*colour + 1] * 255),
+ (unsigned)(fe->colours[3*colour + 2] * 255));
+ if (!fe->css_provider)
+ fe->css_provider = gtk_css_provider_new();
+ if (!gtk_css_provider_load_from_data(
+ GTK_CSS_PROVIDER(fe->css_provider), css_buf, -1, NULL))
+ assert(0 && "Couldn't load CSS");
+ gtk_style_context_add_provider(
+ gtk_widget_get_style_context(fe->window),
+ GTK_STYLE_PROVIDER(fe->css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ gtk_style_context_add_provider(
+ gtk_widget_get_style_context(fe->area),
+ GTK_STYLE_PROVIDER(fe->css_provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+#elif GTK_CHECK_VERSION(3,0,0)
GdkRGBA rgba;
rgba.red = fe->colours[3*colour + 0];
rgba.green = fe->colours[3*colour + 1];
fe->image = NULL;
}
-static void wipe_and_destroy_cairo(frontend *fe, cairo_t *cr)
+static void wipe_and_maybe_destroy_cairo(frontend *fe, cairo_t *cr,
+ int destroy)
{
cairo_set_source_rgb(cr, fe->colours[0], fe->colours[1], fe->colours[2]);
cairo_paint(cr);
- cairo_destroy(cr);
+ if (destroy)
+ cairo_destroy(cr);
}
static void setup_backing_store(frontend *fe)
fe->image = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
fe->pw, fe->ph);
- wipe_and_destroy_cairo(fe, cairo_create(fe->image));
+ wipe_and_maybe_destroy_cairo(fe, cairo_create(fe->image), TRUE);
#ifndef USE_CAIRO_WITHOUT_PIXMAP
- wipe_and_destroy_cairo(fe, gdk_cairo_create(fe->pixmap));
+ wipe_and_maybe_destroy_cairo(fe, gdk_cairo_create(fe->pixmap), TRUE);
+#endif
+#if GTK_CHECK_VERSION(3,22,0)
+ {
+ GdkWindow *gdkwin;
+ cairo_region_t *region;
+ GdkDrawingContext *drawctx;
+ cairo_t *cr;
+
+ gdkwin = gtk_widget_get_window(fe->area);
+ region = gdk_window_get_clip_region(gdkwin);
+ drawctx = gdk_window_begin_draw_frame(gdkwin, region);
+ cr = gdk_drawing_context_get_cairo_context(drawctx);
+ wipe_and_maybe_destroy_cairo(fe, cr, FALSE);
+ gdk_window_end_draw_frame(gdkwin, drawctx);
+ cairo_region_destroy(region);
+ }
+#else
+ wipe_and_maybe_destroy_cairo(
+ fe, gdk_cairo_create(gtk_widget_get_window(fe->area)), TRUE);
#endif
- wipe_and_destroy_cairo(fe, gdk_cairo_create
- (gtk_widget_get_window(fe->area)));
}
static int backing_store_ok(frontend *fe)
button = RIGHT_BUTTON;
else if (event->button == 1)
button = LEFT_BUTTON;
+ else if (event->button == 8 && event->type == GDK_BUTTON_PRESS)
+ button = 'u';
+ else if (event->button == 9 && event->type == GDK_BUTTON_PRESS)
+ button = 'r';
else
return FALSE; /* don't even know what button! */
- if (event->type == GDK_BUTTON_RELEASE)
+ if (event->type == GDK_BUTTON_RELEASE && button >= LEFT_BUTTON)
button += LEFT_RELEASE - LEFT_BUTTON;
if (!midend_process_key(fe->me, event->x - fe->ox,
{
frontend *fe = (frontend *)data;
int x, y;
+ int oldw = fe->w, oldpw = fe->pw, oldh = fe->h, oldph = fe->ph;
x = event->width;
y = event->height;
-
- if (x != fe->w || y != fe->h || !backing_store_ok(fe)) {
+ fe->w = x;
+ fe->h = y;
+ midend_size(fe->me, &x, &y, TRUE);
+ fe->pw = x;
+ fe->ph = y;
+ fe->ox = (fe->w - fe->pw) / 2;
+ fe->oy = (fe->h - fe->ph) / 2;
+
+ if (oldw != fe->w || oldpw != fe->pw ||
+ oldh != fe->h || oldph != fe->ph || !backing_store_ok(fe)) {
if (backing_store_ok(fe))
teardown_backing_store(fe);
-
- fe->w = x;
- fe->h = y;
- midend_size(fe->me, &x, &y, TRUE);
- fe->pw = x;
- fe->ph = y;
- fe->ox = (fe->w - fe->pw) / 2;
- fe->oy = (fe->h - fe->ph) / 2;
-
setup_backing_store(fe);
}
#if GTK_CHECK_VERSION(3,16,0)
gtk_label_set_xalign(label, x);
gtk_label_set_yalign(label, y);
+#elif GTK_CHECK_VERSION(3,14,0)
+ gtk_widget_set_halign(GTK_WIDGET(label),
+ x == 0 ? GTK_ALIGN_START :
+ x == 1 ? GTK_ALIGN_END : GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(GTK_WIDGET(label),
+ y == 0 ? GTK_ALIGN_START :
+ y == 1 ? GTK_ALIGN_END : GTK_ALIGN_CENTER);
#else
gtk_misc_set_alignment(GTK_MISC(label), x, y);
#endif
return FALSE;
}
+#if GTK_CHECK_VERSION(3,0,0)
+static int window_extra_height(frontend *fe)
+{
+ int ret = 0;
+ if (fe->menubar) {
+ GtkRequisition req;
+ gtk_widget_get_preferred_size(fe->menubar, &req, NULL);
+ ret += req.height;
+ }
+ if (fe->statusbar) {
+ GtkRequisition req;
+ gtk_widget_get_preferred_size(fe->statusbar, &req, NULL);
+ ret += req.height;
+ }
+ return ret;
+}
+#endif
+
static void resize_fe(frontend *fe)
{
int x, y;
get_size(fe, &x, &y);
#if GTK_CHECK_VERSION(3,0,0)
- gtk_window_resize_to_geometry(GTK_WINDOW(fe->window), x, y);
+ gtk_window_resize(GTK_WINDOW(fe->window), x, y + window_extra_height(fe));
#else
fe->drawing_area_shrink_pending = FALSE;
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);
midend_new_game(fe->me);
changed_preset(fe);
resize_fe(fe);
+ midend_redraw(fe->me);
}
GdkAtom compound_text_atom, utf8_string_atom;
NULL);
if (gtk_dialog_run(GTK_DIALOG(filesel)) == GTK_RESPONSE_ACCEPT) {
- const char *name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filesel));
+ char *name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filesel));
filesel_name = dupstr(name);
+ g_free(name);
}
gtk_widget_destroy(filesel);
" file \"%.*s\"?",
FILENAME_MAX, name);
if (!message_box(fe->window, "Question", buf, TRUE, MB_YESNO))
- return;
+ goto free_and_return;
}
fp = fopen(name, "w");
- sfree(name);
if (!fp) {
error_box(fe->window, "Unable to open save file");
- return;
+ goto free_and_return;
}
{
sprintf(boxmsg, "Error writing save file: %.400s",
strerror(errno));
error_box(fe->window, boxmsg);
- return;
+ goto free_and_return;
}
}
-
+ free_and_return:
+ sfree(name);
}
}
changed_preset(fe);
resize_fe(fe);
+ midend_redraw(fe->me);
}
}
midend_new_game(fe->me);
resize_fe(fe);
+ midend_redraw(fe->me);
}
static void menu_about_event(GtkMenuItem *menuitem, gpointer data)
extern const int n_xpm_icons;
fe = snew(frontend);
+#if GTK_CHECK_VERSION(3,20,0)
+ fe->css_provider = NULL;
+#endif
fe->timer_active = FALSE;
fe->timer_id = -1;
#endif
{
GdkGeometry geom;
- geom.base_width = geom.base_height = 0;
+ geom.base_width = 0;
+#if GTK_CHECK_VERSION(3,0,0)
+ geom.base_height = window_extra_height(fe);
+ gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), NULL,
+ &geom, GDK_HINT_BASE_SIZE);
+#else
+ geom.base_height = 0;
gtk_window_set_geometry_hints(GTK_WINDOW(fe->window), fe->area,
&geom, GDK_HINT_BASE_SIZE);
+#endif
}
fe->w = -1;
fe->h = -1;
get_size(fe, &x, &y);
#if GTK_CHECK_VERSION(3,0,0)
- gtk_window_set_default_geometry(GTK_WINDOW(fe->window), x, y);
+ gtk_window_set_default_size(GTK_WINDOW(fe->window),
+ x, y + window_extra_height(fe));
#else
fe->drawing_area_shrink_pending = FALSE;
gtk_drawing_area_size(GTK_DRAWING_AREA(fe->area), x, y);