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
|
#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,
|
static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
@ -200,6 +208,7 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int try_grab_keyboard(struct askpass_ctx *ctx)
|
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",
|
"configure_event",
|
||||||
G_CALLBACK(configure_area),
|
G_CALLBACK(configure_area),
|
||||||
&ctx->drawingareas[i]);
|
&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),
|
g_signal_connect(G_OBJECT(ctx->drawingareas[i].area),
|
||||||
"expose_event",
|
"expose_event",
|
||||||
G_CALLBACK(expose_area),
|
G_CALLBACK(expose_area),
|
||||||
&ctx->drawingareas[i]);
|
&ctx->drawingareas[i]);
|
||||||
|
#endif
|
||||||
gtk_widget_show(ctx->drawingareas[i].area);
|
gtk_widget_show(ctx->drawingareas[i].area);
|
||||||
}
|
}
|
||||||
ctx->active_area = rand() % N_DRAWING_AREAS;
|
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,
|
static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event,
|
||||||
gpointer data)
|
gpointer data)
|
||||||
{
|
{
|
||||||
@ -2862,6 +2876,7 @@ static gint unifontsel_expose_area(GtkWidget *widget, GdkEventExpose *event,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static gint unifontsel_configure_area(GtkWidget *widget,
|
static gint unifontsel_configure_area(GtkWidget *widget,
|
||||||
GdkEventConfigure *event, gpointer data)
|
GdkEventConfigure *event, gpointer data)
|
||||||
@ -3097,8 +3112,13 @@ unifontsel *unifontsel_new(const char *wintitle)
|
|||||||
FALSE, FALSE);
|
FALSE, FALSE);
|
||||||
gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg,
|
gdk_colormap_alloc_color(gdk_colormap_get_system(), &fs->preview_bg,
|
||||||
FALSE, FALSE);
|
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_signal_connect(G_OBJECT(fs->preview_area), "expose_event",
|
||||||
G_CALLBACK(unifontsel_expose_area), fs);
|
G_CALLBACK(unifontsel_expose_area), fs);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(fs->preview_area), "configure_event",
|
g_signal_connect(G_OBJECT(fs->preview_area), "configure_event",
|
||||||
G_CALLBACK(unifontsel_configure_area), fs);
|
G_CALLBACK(unifontsel_configure_area), fs);
|
||||||
gtk_widget_set_size_request(fs->preview_area, 1, preview_height);
|
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;
|
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)
|
gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
||||||
{
|
{
|
||||||
struct gui_data *inst = (struct gui_data *)data;
|
struct gui_data *inst = (struct gui_data *)data;
|
||||||
@ -542,20 +602,6 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
|||||||
#else
|
#else
|
||||||
if (inst->term) {
|
if (inst->term) {
|
||||||
Context ctx = get_ctx(inst);
|
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,
|
term_paint(inst->term, ctx,
|
||||||
(event->area.x - inst->window_border) / inst->font_width,
|
(event->area.x - inst->window_border) / inst->font_width,
|
||||||
(event->area.y - inst->window_border) / inst->font_height,
|
(event->area.y - inst->window_border) / inst->font_height,
|
||||||
@ -570,6 +616,7 @@ gint expose_area(GtkWidget *widget, GdkEventExpose *event, gpointer data)
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define KEY_PRESSED(k) \
|
#define KEY_PRESSED(k) \
|
||||||
(inst->keystate[(k) / 32] & (1 << ((k) % 32)))
|
(inst->keystate[(k) / 32] & (1 << ((k) % 32)))
|
||||||
@ -2362,16 +2409,7 @@ Context get_ctx(void *frontend)
|
|||||||
if (dctx->uctx.type == DRAWTYPE_CAIRO) {
|
if (dctx->uctx.type == DRAWTYPE_CAIRO) {
|
||||||
dctx->uctx.u.cairo.widget = GTK_WIDGET(inst->area);
|
dctx->uctx.u.cairo.widget = GTK_WIDGET(inst->area);
|
||||||
dctx->uctx.u.cairo.cr = gdk_cairo_create(target);
|
dctx->uctx.u.cairo.cr = gdk_cairo_create(target);
|
||||||
cairo_get_matrix(dctx->uctx.u.cairo.cr,
|
cairo_setup_dctx(dctx);
|
||||||
&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
|
#endif
|
||||||
return dctx;
|
return dctx;
|
||||||
@ -4172,8 +4210,13 @@ int pt_main(int argc, char **argv)
|
|||||||
G_CALLBACK(focus_event), inst);
|
G_CALLBACK(focus_event), inst);
|
||||||
g_signal_connect(G_OBJECT(inst->area), "configure_event",
|
g_signal_connect(G_OBJECT(inst->area), "configure_event",
|
||||||
G_CALLBACK(configure_area), inst);
|
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_signal_connect(G_OBJECT(inst->area), "expose_event",
|
||||||
G_CALLBACK(expose_area), inst);
|
G_CALLBACK(expose_area), inst);
|
||||||
|
#endif
|
||||||
g_signal_connect(G_OBJECT(inst->area), "button_press_event",
|
g_signal_connect(G_OBJECT(inst->area), "button_press_event",
|
||||||
G_CALLBACK(button_event), inst);
|
G_CALLBACK(button_event), inst);
|
||||||
g_signal_connect(G_OBJECT(inst->area), "button_release_event",
|
g_signal_connect(G_OBJECT(inst->area), "button_release_event",
|
||||||
|
Loading…
Reference in New Issue
Block a user