aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2022-03-03 20:31:33 +0200
committerEli Zaretskii2022-03-03 20:31:33 +0200
commit29ff903bb0379f6fef0f7dc60977e05a8c60f147 (patch)
tree3d59d3c4a0bb8e4f0902bccd431c9de26d9299dd
parent92e2d19fe787ce73db15d1549880b54743c0d929 (diff)
downloademacs-29ff903bb0379f6fef0f7dc60977e05a8c60f147.tar.gz
emacs-29ff903bb0379f6fef0f7dc60977e05a8c60f147.zip
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)
-rw-r--r--src/dispextern.h3
-rw-r--r--src/fringe.c17
-rw-r--r--src/w32term.c15
-rw-r--r--src/xterm.c14
4 files changed, 47 insertions, 2 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index bc5f7a52e08..65801596d5d 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3449,6 +3449,9 @@ bool update_window_fringes (struct window *, bool);
3449 3449
3450void gui_init_fringe (struct redisplay_interface *); 3450void gui_init_fringe (struct redisplay_interface *);
3451 3451
3452extern int max_used_fringe_bitmap;
3453void gui_define_fringe_bitmap (struct frame *, int);
3454
3452#ifdef HAVE_NTGUI 3455#ifdef HAVE_NTGUI
3453void w32_reset_fringes (void); 3456void w32_reset_fringes (void);
3454#endif 3457#endif
diff --git a/src/fringe.c b/src/fringe.c
index f857aedaf02..14148a67ab1 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1802,6 +1802,23 @@ gui_init_fringe (struct redisplay_interface *rif)
1802 } 1802 }
1803} 1803}
1804 1804
1805/* Call frame F's specific define_fringe_bitmap method for a fringe
1806 bitmap number N. Called by various *term.c functions when they
1807 need to display a fringe bitmap whose terminal-specific data is not
1808 available. */
1809void
1810gui_define_fringe_bitmap (struct frame *f, int n)
1811{
1812 struct redisplay_interface *rif = FRAME_RIF (f);
1813
1814 if (!rif || !rif->define_fringe_bitmap || n >= max_used_fringe_bitmap)
1815 return;
1816
1817 struct fringe_bitmap *fb = fringe_bitmaps[n];
1818 if (fb)
1819 rif->define_fringe_bitmap (n, fb->bits, fb->height, fb->width);
1820}
1821
1805#ifdef HAVE_NTGUI 1822#ifdef HAVE_NTGUI
1806void 1823void
1807w32_reset_fringes (void) 1824w32_reset_fringes (void)
diff --git a/src/w32term.c b/src/w32term.c
index 6b41b1d324f..ae99d9948e6 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -777,12 +777,25 @@ w32_draw_fringe_bitmap (struct window *w, struct glyph_row *row,
777 w32_fill_area (f, hdc, face->background, 777 w32_fill_area (f, hdc, face->background,
778 p->bx, p->by, p->nx, p->ny); 778 p->bx, p->by, p->nx, p->ny);
779 779
780 if (p->which && p->which < max_fringe_bmp) 780 if (p->which
781 && p->which < max_fringe_bmp
782 && p->which < max_used_fringe_bitmap)
781 { 783 {
782 HBITMAP pixmap = fringe_bmp[p->which]; 784 HBITMAP pixmap = fringe_bmp[p->which];
783 HDC compat_hdc; 785 HDC compat_hdc;
784 HANDLE horig_obj; 786 HANDLE horig_obj;
785 787
788 if (!fringe_bmp[p->which])
789 {
790 /* This fringe bitmap is known to fringe.c, but lacks the
791 HBITMAP data which shadows that bitmap. This is typical
792 to define-fringe-bitmap being called when the selected
793 frame was not a GUI frame, for example, when packages
794 that define fringe bitmaps are loaded by a daemon Emacs.
795 Create the missing HBITMAP now. */
796 gui_define_fringe_bitmap (f, p->which);
797 }
798
786 compat_hdc = CreateCompatibleDC (hdc); 799 compat_hdc = CreateCompatibleDC (hdc);
787 800
788 SaveDC (hdc); 801 SaveDC (hdc);
diff --git a/src/xterm.c b/src/xterm.c
index 59413eafd48..9a8c3e9ad76 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1426,7 +1426,9 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
1426 } 1426 }
1427 1427
1428#ifdef USE_CAIRO 1428#ifdef USE_CAIRO
1429 if (p->which && p->which < max_fringe_bmp) 1429 if (p->which
1430 && p->which < max_fringe_bmp
1431 && p->which < max_used_fringe_bitmap)
1430 { 1432 {
1431 XGCValues gcv; 1433 XGCValues gcv;
1432 1434
@@ -1436,6 +1438,16 @@ x_draw_fringe_bitmap (struct window *w, struct glyph_row *row, struct draw_fring
1436 : f->output_data.x->cursor_pixel) 1438 : f->output_data.x->cursor_pixel)
1437 : face->foreground)); 1439 : face->foreground));
1438 XSetBackground (display, gc, face->background); 1440 XSetBackground (display, gc, face->background);
1441 if (!fringe_bmp[p->which])
1442 {
1443 /* This fringe bitmap is known to fringe.c, but lacks the
1444 cairo_pattern_t pattern which shadows that bitmap. This
1445 is typical to define-fringe-bitmap being called when the
1446 selected frame was not a GUI frame, for example, when
1447 packages that define fringe bitmaps are loaded by a
1448 daemon Emacs. Create the missing pattern now. */
1449 gui_define_fringe_bitmap (f, p->which);
1450 }
1439 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh, 1451 x_cr_draw_image (f, gc, fringe_bmp[p->which], 0, p->dh,
1440 p->wd, p->h, p->x, p->y, p->overlay_p); 1452 p->wd, p->h, p->x, p->y, p->overlay_p);
1441 XSetForeground (display, gc, gcv.foreground); 1453 XSetForeground (display, gc, gcv.foreground);