mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-10 01:48:00 +00:00
GTK3 port: support the new "draw" signal.
This replaces GTK 1/2's "expose_event", and provides a ready-made cairo_t to do the drawing with. My previous work has already separated all constructions of a cairo_t from the subsequent drawing with it, so the new draw event handlers just have to call the latter without the former.
This commit is contained in:
parent
280b14f129
commit
afae35eb90
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user