diff --git a/unix/gtkask.c b/unix/gtkask.c index 1d6e8768..4ee1c8ed 100644 --- a/unix/gtkask.c +++ b/unix/gtkask.c @@ -185,6 +185,14 @@ static void askpass_redraw_gdk(GdkWindow *win, struct drawing_area_ctx *ctx) } #endif +#if GTK_CHECK_VERSION(3,0,0) +static gint draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + struct drawing_area_ctx *ctx = (struct drawing_area_ctx *)data; + askpass_redraw_cairo(cr, ctx); + return TRUE; +} +#else static gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { @@ -200,6 +208,7 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event, return TRUE; } +#endif static int try_grab_keyboard(struct askpass_ctx *ctx) { @@ -288,10 +297,17 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, "configure_event", G_CALLBACK(configure_area), &ctx->drawingareas[i]); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(ctx->drawingareas[i].area), + "draw", + G_CALLBACK(draw_area), + &ctx->drawingareas[i]); +#else g_signal_connect(G_OBJECT(ctx->drawingareas[i].area), "expose_event", G_CALLBACK(expose_area), &ctx->drawingareas[i]); +#endif gtk_widget_show(ctx->drawingareas[i].area); } ctx->active_area = rand() % N_DRAWING_AREAS; diff --git a/unix/gtkfont.c b/unix/gtkfont.c index 0fcc4d4b..b504a7c8 100644 --- a/unix/gtkfont.c +++ b/unix/gtkfont.c @@ -2841,6 +2841,20 @@ static void alias_resolve(GtkTreeView *treeview, GtkTreePath *path, } } +#if GTK_CHECK_VERSION(3,0,0) +static gint unifontsel_draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + unifontsel_internal *fs = (unifontsel_internal *)data; + unifont_drawctx dctx; + + dctx.type = DRAWTYPE_CAIRO; + dctx.u.cairo.widget = widget; + dctx.u.cairo.cr = cr; + unifontsel_draw_preview_text_inner(&dctx, fs); + + return TRUE; +} +#else static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { @@ -2862,6 +2876,7 @@ static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event, return TRUE; } +#endif static gint unifontsel_configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) @@ -3097,8 +3112,13 @@ unifontsel *unifontsel_new(const char *wintitle) FALSE, FALSE); gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg, FALSE, FALSE); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(fs->preview_area), "draw", + G_CALLBACK(unifontsel_draw_area), fs); +#else g_signal_connect(G_OBJECT(fs->preview_area), "expose_event", G_CALLBACK(unifontsel_expose_area), fs); +#endif g_signal_connect(G_OBJECT(fs->preview_area), "configure_event", G_CALLBACK(unifontsel_configure_area), fs); gtk_widget_set_size_request(fs->preview_area, 1, preview_height); diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 108d4cb9..2ec84d57 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -521,6 +521,66 @@ gint configure_area(GtkWidget *widget, GdkEventConfigure *event, gpointer data) return TRUE; } +#ifdef DRAW_TEXT_CAIRO +static void cairo_setup_dctx(struct draw_ctx *dctx) +{ + cairo_get_matrix(dctx->uctx.u.cairo.cr, + &dctx->uctx.u.cairo.origmatrix); + cairo_set_line_width(dctx->uctx.u.cairo.cr, 1.0); + cairo_set_line_cap(dctx->uctx.u.cairo.cr, CAIRO_LINE_CAP_SQUARE); + cairo_set_line_join(dctx->uctx.u.cairo.cr, CAIRO_LINE_JOIN_MITER); + /* This antialiasing setting appears to be ignored for Pango + * font rendering but honoured for stroking and filling paths; + * I don't quite understand the logic of that, but I won't + * complain since it's exactly what I happen to want */ + cairo_set_antialias(dctx->uctx.u.cairo.cr, CAIRO_ANTIALIAS_NONE); +} +#endif + +#if GTK_CHECK_VERSION(3,0,0) +static gint draw_area(GtkWidget *widget, cairo_t *cr, gpointer data) +{ + struct gui_data *inst = (struct gui_data *)data; + + if (inst->term) { + struct draw_ctx adctx, *dctx = &adctx; + GdkRectangle dirtyrect; + + dctx->inst = inst; + dctx->uctx.type = DRAWTYPE_CAIRO; + dctx->uctx.u.cairo.widget = widget; + dctx->uctx.u.cairo.cr = cr; + cairo_setup_dctx(dctx); + + gdk_cairo_get_clip_rectangle(cr, &dirtyrect); + + /* + * As in window.c, we clear the 'immediately' flag in the + * term_paint() call if the terminal has an update pending, in + * case we're constrained within this event to only draw on + * the exposed rectangle of the window. (Because if the whole + * of a character cell needs a redraw due to a terminal + * contents change, the last thing we want is to give it a + * _partial_ redraw here due to system-imposed clipping, and + * then have the next main terminal update believe it's been + * redrawn in full.) + * + * I don't actually know if GTK draw events will constrain us + * in this way, but it's best to be careful... + */ + term_paint(inst->term, dctx, + (dirtyrect.x - inst->window_border) / inst->font_width, + (dirtyrect.y - inst->window_border) / inst->font_height, + (dirtyrect.x + dirtyrect.width - + inst->window_border) / inst->font_width, + (dirtyrect.y + dirtyrect.height - + inst->window_border) / inst->font_height, + !inst->term->window_update_pending); + } + + return TRUE; +} +#else gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) { struct gui_data *inst = (struct gui_data *)data; @@ -542,20 +602,6 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) #else if (inst->term) { Context ctx = get_ctx(inst); - /* - * As in window.c, we clear the 'immediately' flag in the - * term_paint() call if the terminal has an update pending, in - * case we're constrained within this event to only draw on - * the exposed rectangle of the window. (Because if the whole - * of a character cell needs a redraw due to a terminal - * contents change, the last thing we want is to give it a - * _partial_ redraw here due to system-imposed clipping, and - * then have the next main terminal update believe it's been - * redrawn in full.) - * - * I don't actually know if GTK expose events will constrain - * us in this way, but it's best to be careful... - */ term_paint(inst->term, ctx, (event->area.x - inst->window_border) / inst->font_width, (event->area.y - inst->window_border) / inst->font_height, @@ -570,6 +616,7 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data) return TRUE; } +#endif #define KEY_PRESSED(k) \ (inst->keystate[(k) / 32] & (1 << ((k) % 32))) @@ -2362,16 +2409,7 @@ Context get_ctx(void *frontend) if (dctx->uctx.type == DRAWTYPE_CAIRO) { dctx->uctx.u.cairo.widget = GTK_WIDGET(inst->area); dctx->uctx.u.cairo.cr = gdk_cairo_create(target); - cairo_get_matrix(dctx->uctx.u.cairo.cr, - &dctx->uctx.u.cairo.origmatrix); - cairo_set_line_width(dctx->uctx.u.cairo.cr, 1.0); - cairo_set_line_cap(dctx->uctx.u.cairo.cr, CAIRO_LINE_CAP_SQUARE); - cairo_set_line_join(dctx->uctx.u.cairo.cr, CAIRO_LINE_JOIN_MITER); - /* This antialiasing setting appears to be ignored for Pango - * font rendering but honoured for stroking and filling paths; - * I don't quite understand the logic of that, but I won't - * complain since it's exactly what I happen to want */ - cairo_set_antialias(dctx->uctx.u.cairo.cr, CAIRO_ANTIALIAS_NONE); + cairo_setup_dctx(dctx); } #endif return dctx; @@ -4172,8 +4210,13 @@ int pt_main(int argc, char **argv) G_CALLBACK(focus_event), inst); g_signal_connect(G_OBJECT(inst->area), "configure_event", G_CALLBACK(configure_area), inst); +#if GTK_CHECK_VERSION(3,0,0) + g_signal_connect(G_OBJECT(inst->area), "draw", + G_CALLBACK(draw_area), inst); +#else g_signal_connect(G_OBJECT(inst->area), "expose_event", G_CALLBACK(expose_area), inst); +#endif g_signal_connect(G_OBJECT(inst->area), "button_press_event", G_CALLBACK(button_event), inst); g_signal_connect(G_OBJECT(inst->area), "button_release_event",