diff options
| author | Eli Zaretskii | 2022-03-03 20:31:33 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2022-03-03 20:31:33 +0200 |
| commit | 29ff903bb0379f6fef0f7dc60977e05a8c60f147 (patch) | |
| tree | 3d59d3c4a0bb8e4f0902bccd431c9de26d9299dd | |
| parent | 92e2d19fe787ce73db15d1549880b54743c0d929 (diff) | |
| download | emacs-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.h | 3 | ||||
| -rw-r--r-- | src/fringe.c | 17 | ||||
| -rw-r--r-- | src/w32term.c | 15 | ||||
| -rw-r--r-- | src/xterm.c | 14 |
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 | ||
| 3450 | void gui_init_fringe (struct redisplay_interface *); | 3450 | void gui_init_fringe (struct redisplay_interface *); |
| 3451 | 3451 | ||
| 3452 | extern int max_used_fringe_bitmap; | ||
| 3453 | void gui_define_fringe_bitmap (struct frame *, int); | ||
| 3454 | |||
| 3452 | #ifdef HAVE_NTGUI | 3455 | #ifdef HAVE_NTGUI |
| 3453 | void w32_reset_fringes (void); | 3456 | void 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. */ | ||
| 1809 | void | ||
| 1810 | gui_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 |
| 1806 | void | 1823 | void |
| 1807 | w32_reset_fringes (void) | 1824 | w32_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); |