Avoid crashes when fringe bitmaps are defined in daemon mode
* src/dispextern.h (gui_define_fringe_bitmap): Add prototype. (max_used_fringe_bitmap): Add declaration. * src/fringe.c (gui_define_fringe_bitmap): New function. * src/w32term.c (w32_draw_fringe_bitmap): * src/xterm.c (x_draw_fringe_bitmap) [USE_CAIRO]: Call 'gui_define_fringe_bitmap' if the terminal-specific bitmap data is not available when a fringe bitmap is about to be drawn. Don't try to draw a bitmap that is not known to fringe.c. (Bug#54183)
This commit is contained in:
parent
92e2d19fe7
commit
29ff903bb0
4 changed files with 47 additions and 2 deletions
|
@ -3449,6 +3449,9 @@ bool update_window_fringes (struct window *, bool);
|
|||
|
||||
void gui_init_fringe (struct redisplay_interface *);
|
||||
|
||||
extern int max_used_fringe_bitmap;
|
||||
void gui_define_fringe_bitmap (struct frame *, int);
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
void w32_reset_fringes (void);
|
||||
#endif
|
||||
|
|
17
src/fringe.c
17
src/fringe.c
|
@ -1802,6 +1802,23 @@ gui_init_fringe (struct redisplay_interface *rif)
|
|||
}
|
||||
}
|
||||
|
||||
/* Call frame F's specific define_fringe_bitmap method for a fringe
|
||||
bitmap number N. Called by various *term.c functions when they
|
||||
need to display a fringe bitmap whose terminal-specific data is not
|
||||
available. */
|
||||
void
|
||||
gui_define_fringe_bitmap (struct frame *f, int n)
|
||||
{
|
||||
struct redisplay_interface *rif = FRAME_RIF (f);
|
||||
|
||||
if (!rif || !rif->define_fringe_bitmap || n >= max_used_fringe_bitmap)
|
||||
return;
|
||||
|
||||
struct fringe_bitmap *fb = fringe_bitmaps[n];
|
||||
if (fb)
|
||||
rif->define_fringe_bitmap (n, fb->bits, fb->height, fb->width);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
void
|
||||
w32_reset_fringes (void)
|
||||
|
|
|
@ -777,12 +777,25 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
|
|||
w32_fill_area (f, hdc, face->background,
|
||||
p->bx, p->by, p->nx, p->ny);
|
||||
|
||||
if (p->which && p->which < max_fringe_bmp)
|
||||
if (p->which
|
||||
&& p->which < max_fringe_bmp
|
||||
&& p->which < max_used_fringe_bitmap)
|
||||
{
|
||||
HBITMAP pixmap = fringe_bmp[p->which];
|
||||
HDC compat_hdc;
|
||||
HANDLE horig_obj;
|
||||
|
||||
if (!fringe_bmp[p->which])
|
||||
{
|
||||
/* This fringe bitmap is known to fringe.c, but lacks the
|
||||
HBITMAP data which shadows that bitmap. This is typical
|
||||
to define-fringe-bitmap being called when the selected
|
||||
frame was not a GUI frame, for example, when packages
|
||||
that define fringe bitmaps are loaded by a daemon Emacs.
|
||||
Create the missing HBITMAP now. */
|
||||
gui_define_fringe_bitmap (f, p->which);
|
||||
}
|
||||
|
||||
compat_hdc = CreateCompatibleDC (hdc);
|
||||
|
||||
SaveDC (hdc);
|
||||
|
|
14
src/xterm.c
14
src/xterm.c
|
@ -1426,7 +1426,9 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
|
|||
}
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
if (p->which && p->which < max_fringe_bmp)
|
||||
if (p->which
|
||||
&& p->which < max_fringe_bmp
|
||||
&& p->which < max_used_fringe_bitmap)
|
||||
{
|
||||
XGCValues gcv;
|
||||
|
||||
|
@ -1436,6 +1438,16 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
|
|||
: f->output_data.x->cursor_pixel)
|
||||
: face->foreground));
|
||||
XSetBackground (display, gc, face->background);
|
||||
if (!fringe_bmp[p->which])
|
||||
{
|
||||
/* This fringe bitmap is known to fringe.c, but lacks the
|
||||
cairo_pattern_t pattern which shadows that bitmap. This
|
||||
is typical to define-fringe-bitmap being called when the
|
||||
selected frame was not a GUI frame, for example, when
|
||||
packages that define fringe bitmaps are loaded by a
|
||||
daemon Emacs. Create the missing pattern now. */
|
||||
gui_define_fringe_bitmap (f, p->which);
|
||||
}
|
||||
x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
|
||||
p->wd, p->h, p->x, p->y, p->overlay_p);
|
||||
XSetForeground (display, gc, gcv.foreground);
|
||||
|
|
Loading…
Add table
Reference in a new issue