aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2024-12-20 11:12:22 +0800
committerPo Lu2024-12-20 11:12:22 +0800
commitcc5afea98e8efb1a04baedf98e66863d31974ae6 (patch)
tree6d00d73bc98de1555d28fb1b5121cbec5cbc16f5
parente166803f8c1f1870cefb4f5b7828422a145cd3d4 (diff)
downloademacs-cc5afea98e8efb1a04baedf98e66863d31974ae6.tar.gz
emacs-cc5afea98e8efb1a04baedf98e66863d31974ae6.zip
Enable TTY child frames on MS-DOS
* src/conf_post.h (ENOTSUP): Define to ENOSYS as msdos.h once did. (IFTODT): Copy definition from Gnulib. * src/dispnew.c (is_tty_frame): Also test FRAME_MSDOS_P. * src/frame.c (tty_child_pos_param, tty_child_size_param): Export functions. * src/msdos.c (mouse_get_xy, mouse_moveto, mouse_pressed): Offset mouse positions by those of the selected frame. (it_face_override): New function. (IT_set_face): New argument F. Load FACE_ID from its face cache. (IT_write_glyphs): Track the frames on which glyphs were generated and apply faces from their individual face caches. (IT_write_glyphs_with_face): New function. (tty_draw_row_with_mouse_face): Reimplement in line with tty.c and eliminate an obsolete optimization. (IT_clear_end_of_line, IT_clear_screen): Load faces from the cache of the provided frame. (IT_set_frame_parameters): Adjust frame geometry and garbage frames after geometry parameters change as a child frame. (BUILD_CHAR_GLYPH): Accept new parameter F. (IT_menu_display): Offset cursor positions by those of the selected frame. * src/msdos.h (ENOTSUP): Move to conf_post.h for Gnulib. * src/xdisp.c (redisplay_internal): Redisplay MSDOS frames unconditionally as with terminal frames.
-rw-r--r--src/conf_post.h7
-rw-r--r--src/dispnew.c2
-rw-r--r--src/frame.c4
-rw-r--r--src/frame.h4
-rw-r--r--src/msdos.c207
-rw-r--r--src/msdos.h1
-rw-r--r--src/xdisp.c3
7 files changed, 128 insertions, 100 deletions
diff --git a/src/conf_post.h b/src/conf_post.h
index e68d5a56d9b..9d3f5711bef 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -480,5 +480,10 @@ extern int emacs_setenv_TZ (char const *);
480/* These are required by file-has-acl.c but defined in dirent.h and 480/* These are required by file-has-acl.c but defined in dirent.h and
481 errno.h, which are not generated on DOS. */ 481 errno.h, which are not generated on DOS. */
482#define _GL_DT_NOTDIR 0x100 /* Not a directory */ 482#define _GL_DT_NOTDIR 0x100 /* Not a directory */
483#define ENOTSUP 2007 483#define ENOTSUP ENOSYS
484# define IFTODT(mode) \
485 (S_ISREG (mode) ? DT_REG : S_ISDIR (mode) ? DT_DIR \
486 : S_ISLNK (mode) ? DT_LNK : S_ISBLK (mode) ? DT_BLK \
487 : S_ISCHR (mode) ? DT_CHR : S_ISFIFO (mode) ? DT_FIFO \
488 : S_ISSOCK (mode) ? DT_SOCK : DT_UNKNOWN)
484#endif /* MSDOS */ 489#endif /* MSDOS */
diff --git a/src/dispnew.c b/src/dispnew.c
index 2e95016b5f3..180bc173f31 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3468,7 +3468,7 @@ tty_raise_lower_frame (struct frame *f, bool raise)
3468bool 3468bool
3469is_tty_frame (struct frame *f) 3469is_tty_frame (struct frame *f)
3470{ 3470{
3471 return FRAME_TERMCAP_P (f); 3471 return FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f);
3472} 3472}
3473 3473
3474/* Return true if frame F is a tty child frame. */ 3474/* Return true if frame F is a tty child frame. */
diff --git a/src/frame.c b/src/frame.c
index 5518201fca7..250e7e53dd4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -1390,7 +1390,7 @@ get_future_frame_param (Lisp_Object parameter,
1390 1390
1391#endif 1391#endif
1392 1392
1393static int 1393int
1394tty_child_pos_param (struct frame *child, Lisp_Object key, 1394tty_child_pos_param (struct frame *child, Lisp_Object key,
1395 Lisp_Object params, int dflt) 1395 Lisp_Object params, int dflt)
1396{ 1396{
@@ -1404,7 +1404,7 @@ tty_child_pos_param (struct frame *child, Lisp_Object key,
1404 return dflt; 1404 return dflt;
1405} 1405}
1406 1406
1407static int 1407int
1408tty_child_size_param (struct frame *child, Lisp_Object key, 1408tty_child_size_param (struct frame *child, Lisp_Object key,
1409 Lisp_Object params, int dflt) 1409 Lisp_Object params, int dflt)
1410{ 1410{
diff --git a/src/frame.h b/src/frame.h
index cb03d5550bb..9ed2f66be22 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1490,6 +1490,10 @@ extern struct frame *decode_live_frame (Lisp_Object);
1490extern struct frame *decode_any_frame (Lisp_Object); 1490extern struct frame *decode_any_frame (Lisp_Object);
1491extern struct frame *make_initial_frame (void); 1491extern struct frame *make_initial_frame (void);
1492extern struct frame *make_frame (bool); 1492extern struct frame *make_frame (bool);
1493extern int tty_child_pos_param (struct frame *, Lisp_Object,
1494 Lisp_Object, int);
1495extern int tty_child_size_param (struct frame *, Lisp_Object,
1496 Lisp_Object, int);
1493#ifdef HAVE_WINDOW_SYSTEM 1497#ifdef HAVE_WINDOW_SYSTEM
1494extern bool display_available (void); 1498extern bool display_available (void);
1495#endif 1499#endif
diff --git a/src/msdos.c b/src/msdos.c
index 42eee89d748..78f53d5511c 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -237,11 +237,12 @@ static void
237mouse_get_xy (int *x, int *y) 237mouse_get_xy (int *x, int *y)
238{ 238{
239 union REGS regs; 239 union REGS regs;
240 struct frame *f = SELECTED_FRAME ();
240 241
241 regs.x.ax = 0x0003; 242 regs.x.ax = 0x0003;
242 int86 (0x33, &regs, &regs); 243 int86 (0x33, &regs, &regs);
243 *x = regs.x.cx / 8; 244 *x = (regs.x.cx / 8) - f->left_pos;
244 *y = regs.x.dx / 8; 245 *y = (regs.x.dx / 8) - f->top_pos;
245} 246}
246 247
247void 248void
@@ -249,12 +250,15 @@ mouse_moveto (int x, int y)
249{ 250{
250 union REGS regs; 251 union REGS regs;
251 struct tty_display_info *tty = CURTTY (); 252 struct tty_display_info *tty = CURTTY ();
253 struct frame *f = SELECTED_FRAME ();
252 254
253 if (tty->termscript) 255 if (tty->termscript)
254 fprintf (tty->termscript, "<M_XY=%dx%d>", x, y); 256 fprintf (tty->termscript, "<M_XY=%dx%d>", x, y);
255 regs.x.ax = 0x0004; 257 regs.x.ax = 0x0004;
256 mouse_last_x = regs.x.cx = x * 8; 258 mouse_last_x = regs.x.cx = x * 8;
257 mouse_last_y = regs.x.dx = y * 8; 259 mouse_last_y = regs.x.dx = y * 8;
260 regs.x.cx += f->left_pos * 8;
261 regs.x.dx += f->top_pos * 8;
258 int86 (0x33, &regs, &regs); 262 int86 (0x33, &regs, &regs);
259} 263}
260 264
@@ -262,6 +266,7 @@ static int
262mouse_pressed (int b, int *xp, int *yp) 266mouse_pressed (int b, int *xp, int *yp)
263{ 267{
264 union REGS regs; 268 union REGS regs;
269 struct frame *f = SELECTED_FRAME ();
265 270
266 if (b >= mouse_button_count) 271 if (b >= mouse_button_count)
267 return 0; 272 return 0;
@@ -269,7 +274,10 @@ mouse_pressed (int b, int *xp, int *yp)
269 regs.x.bx = mouse_button_translate[b]; 274 regs.x.bx = mouse_button_translate[b];
270 int86 (0x33, &regs, &regs); 275 int86 (0x33, &regs, &regs);
271 if (regs.x.bx) 276 if (regs.x.bx)
272 *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; 277 {
278 *xp = regs.x.cx / 8 - f->left_pos;
279 *yp = regs.x.dx / 8 - f->top_pos;
280 }
273 return (regs.x.bx != 0); 281 return (regs.x.bx != 0);
274} 282}
275 283
@@ -789,19 +797,23 @@ IT_ring_bell (struct frame *f)
789 } 797 }
790} 798}
791 799
800/* If otherwise than -1, a face ID that will override the FACE argument
801 to IT_set_face. */
802static int it_face_override = -1;
803
792/* Given a face id FACE, extract the face parameters to be used for 804/* Given a face id FACE, extract the face parameters to be used for
793 display until the face changes. The face parameters (actually, its 805 display until the face changes. The face parameters (actually, its
794 color) are used to construct the video attribute byte for each 806 color) are used to construct the video attribute byte for each
795 glyph during the construction of the buffer that is then blitted to 807 glyph during the construction of the buffer that is then blitted to
796 the video RAM. */ 808 the video RAM. */
797static void 809static void
798IT_set_face (int face) 810IT_set_face (struct frame *f, int face_id)
799{ 811{
800 struct frame *sf = SELECTED_FRAME (); 812 int face = (it_face_override == -1 ? face_id : it_face_override);
801 struct face *fp = FACE_FROM_ID_OR_NULL (sf, face); 813 struct face *fp = FACE_FROM_ID_OR_NULL (f, face);
802 struct face *dfp = FACE_FROM_ID_OR_NULL (sf, DEFAULT_FACE_ID); 814 struct face *dfp = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID);
803 unsigned long fg, bg, dflt_fg, dflt_bg; 815 unsigned long fg, bg, dflt_fg, dflt_bg;
804 struct tty_display_info *tty = FRAME_TTY (sf); 816 struct tty_display_info *tty = FRAME_TTY (f);
805 817
806 if (!fp) 818 if (!fp)
807 { 819 {
@@ -822,13 +834,13 @@ IT_set_face (int face)
822 16 colors to be available for the background, since Emacs switches 834 16 colors to be available for the background, since Emacs switches
823 on this mode (and loses the blinking attribute) at startup. */ 835 on this mode (and loses the blinking attribute) at startup. */
824 if (fg == FACE_TTY_DEFAULT_COLOR || fg == FACE_TTY_DEFAULT_FG_COLOR) 836 if (fg == FACE_TTY_DEFAULT_COLOR || fg == FACE_TTY_DEFAULT_FG_COLOR)
825 fg = FRAME_FOREGROUND_PIXEL (sf); 837 fg = FRAME_FOREGROUND_PIXEL (f);
826 else if (fg == FACE_TTY_DEFAULT_BG_COLOR) 838 else if (fg == FACE_TTY_DEFAULT_BG_COLOR)
827 fg = FRAME_BACKGROUND_PIXEL (sf); 839 fg = FRAME_BACKGROUND_PIXEL (f);
828 if (bg == FACE_TTY_DEFAULT_COLOR || bg == FACE_TTY_DEFAULT_BG_COLOR) 840 if (bg == FACE_TTY_DEFAULT_COLOR || bg == FACE_TTY_DEFAULT_BG_COLOR)
829 bg = FRAME_BACKGROUND_PIXEL (sf); 841 bg = FRAME_BACKGROUND_PIXEL (f);
830 else if (bg == FACE_TTY_DEFAULT_FG_COLOR) 842 else if (bg == FACE_TTY_DEFAULT_FG_COLOR)
831 bg = FRAME_FOREGROUND_PIXEL (sf); 843 bg = FRAME_FOREGROUND_PIXEL (f);
832 844
833 /* Make sure highlighted lines really stand out, come what may. */ 845 /* Make sure highlighted lines really stand out, come what may. */
834 if (fp->tty_reverse_p && (fg == dflt_fg && bg == dflt_bg)) 846 if (fp->tty_reverse_p && (fg == dflt_fg && bg == dflt_bg))
@@ -876,8 +888,8 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
876 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y); 888 int offset = 2 * (new_pos_X + screen_size_X * new_pos_Y);
877 register int sl = str_len; 889 register int sl = str_len;
878 struct tty_display_info *tty = FRAME_TTY (f); 890 struct tty_display_info *tty = FRAME_TTY (f);
879 struct frame *sf;
880 unsigned char *conversion_buffer; 891 unsigned char *conversion_buffer;
892 struct frame *cf_frame = f;
881 893
882 /* If terminal_coding does any conversion, use it, otherwise use 894 /* If terminal_coding does any conversion, use it, otherwise use
883 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here 895 safe_terminal_coding. We can't use CODING_REQUIRE_ENCODING here
@@ -889,14 +901,12 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
889 901
890 if (str_len <= 0) return; 902 if (str_len <= 0) return;
891 903
892 sf = SELECTED_FRAME ();
893
894 /* Since faces get cached and uncached behind our back, we can't 904 /* Since faces get cached and uncached behind our back, we can't
895 rely on their indices in the cache being consistent across 905 rely on their indices in the cache being consistent across
896 invocations. So always reset the screen face to the default 906 invocations. So always reset the screen face to the default
897 face of the frame, before writing glyphs, and let the glyphs 907 face of the frame, before writing glyphs, and let the glyphs
898 set the right face if it's different from the default. */ 908 set the right face if it's different from the default. */
899 IT_set_face (DEFAULT_FACE_ID); 909 IT_set_face (f, DEFAULT_FACE_ID);
900 910
901 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at 911 /* The mode bit CODING_MODE_LAST_BLOCK should be set to 1 only at
902 the tail. */ 912 the tail. */
@@ -910,8 +920,10 @@ IT_write_glyphs (struct frame *f, struct glyph *str, int str_len)
910 /* If the face of this glyph is different from the current 920 /* If the face of this glyph is different from the current
911 screen face, update the screen attribute byte. */ 921 screen face, update the screen attribute byte. */
912 cf = str->face_id; 922 cf = str->face_id;
913 if (cf != screen_face) 923 if ((cf != screen_face && cf != it_face_override)
914 IT_set_face (cf); /* handles invalid faces gracefully */ 924 || cf_frame != str->frame)
925 IT_set_face (str->frame, cf); /* handles invalid faces gracefully */
926 cf_frame = str->frame;
915 927
916 /* Identify a run of glyphs with the same face. */ 928 /* Identify a run of glyphs with the same face. */
917 for (n = 1; n < sl; ++n) 929 for (n = 1; n < sl; ++n)
@@ -964,6 +976,18 @@ popup_activated (void)
964 return mouse_preempted; 976 return mouse_preempted;
965} 977}
966 978
979/* Write a string of glyphs STRING of length LEN to F, disregarding
980 their invidiual faces in favor of FACE. */
981
982static void
983IT_write_glyphs_with_face (struct frame *f, struct glyph *string,
984 int len, int face_id)
985{
986 it_face_override = face_id;
987 IT_write_glyphs (f, string, len);
988 it_face_override = -1;
989}
990
967/* Draw TEXT_AREA glyphs between START and END of glyph row ROW on 991/* Draw TEXT_AREA glyphs between START and END of glyph row ROW on
968 window W. X is relative to TEXT_AREA in W. HL is a face override 992 window W. X is relative to TEXT_AREA in W. HL is a face override
969 for drawing the glyphs. */ 993 for drawing the glyphs. */
@@ -975,70 +999,38 @@ tty_draw_row_with_mouse_face (struct window *w, struct glyph_row *row,
975 struct frame *f = XFRAME (WINDOW_FRAME (w)); 999 struct frame *f = XFRAME (WINDOW_FRAME (w));
976 struct tty_display_info *tty = FRAME_TTY (f); 1000 struct tty_display_info *tty = FRAME_TTY (f);
977 Mouse_HLInfo *hlinfo = &tty->mouse_highlight; 1001 Mouse_HLInfo *hlinfo = &tty->mouse_highlight;
1002 int nglyphs = end_hpos - start_hpos;
1003 int pos_y, pos_x, save_y, save_x;
978 1004
979 if (hl == DRAW_MOUSE_FACE) 1005 if (end_hpos >= row->used[TEXT_AREA])
980 { 1006 nglyphs = row->used[TEXT_AREA] - start_hpos;
981 int vpos = row->y + WINDOW_TOP_EDGE_Y (w); 1007 pos_y = row->y + WINDOW_TOP_EDGE_Y (w);
982 int kstart = (start_hpos + WINDOW_LEFT_EDGE_X (w) 1008 pos_x = (row->used[LEFT_MARGIN_AREA] + start_hpos
983 + row->used[LEFT_MARGIN_AREA]); 1009 + WINDOW_LEFT_EDGE_X (w));
984 int nglyphs = end_hpos - start_hpos;
985 int offset = ScreenPrimary + 2*(vpos*screen_size_X + kstart) + 1;
986 int start_offset = offset;
987 1010
988 if (end_hpos >= row->used[TEXT_AREA]) 1011 /* Save current cursor position. */
989 nglyphs = row->used[TEXT_AREA] - start_hpos; 1012 save_x = f->left_pos + new_pos_X;
1013 save_y = f->top_pos + new_pos_Y;
990 1014
991 if (tty->termscript) 1015 /* This applies child frame offsets. */
992 fprintf (tty->termscript, "\n<MH+ %d-%d:%d>", 1016 cursor_to (f, pos_y, pos_x);
993 kstart, kstart + nglyphs - 1, vpos); 1017 mouse_off ();
994 1018
995 mouse_off (); 1019 /* Write the glyphs and restore cursor position. */
996 IT_set_face (hlinfo->mouse_face_face_id);
997 /* Since we are going to change only the _colors_ of already
998 displayed text, there's no need to go through all the pain of
999 generating and encoding the text from the glyphs. Instead,
1000 we simply poke the attribute byte of each affected position
1001 in video memory with the colors computed by IT_set_face! */
1002 _farsetsel (_dos_ds);
1003 while (nglyphs--)
1004 {
1005 _farnspokeb (offset, ScreenAttrib);
1006 offset += 2;
1007 }
1008 if (screen_virtual_segment)
1009 dosv_refresh_virtual_screen (start_offset, end_hpos - start_hpos);
1010 mouse_on ();
1011 }
1012 else if (hl == DRAW_NORMAL_TEXT)
1013 {
1014 /* We are removing a previously-drawn mouse highlight. The
1015 safest way to do so is to redraw the glyphs anew, since all
1016 kinds of faces and display tables could have changed behind
1017 our back. */
1018 int nglyphs = end_hpos - start_hpos;
1019 int save_x = new_pos_X, save_y = new_pos_Y;
1020
1021 if (end_hpos >= row->used[TEXT_AREA])
1022 nglyphs = row->used[TEXT_AREA] - start_hpos;
1023
1024 /* IT_write_glyphs writes at cursor position, so we need to
1025 temporarily move cursor coordinates to the beginning of
1026 the highlight region. */
1027 new_pos_X = start_hpos + WINDOW_LEFT_EDGE_X (w);
1028 /* The coordinates supplied by the caller are relative to the
1029 text area, not the window itself. */
1030 new_pos_X += row->used[LEFT_MARGIN_AREA];
1031 new_pos_Y = row->y + WINDOW_TOP_EDGE_Y (w);
1032 1020
1033 if (tty->termscript) 1021 if (hl == DRAW_MOUSE_FACE)
1034 fprintf (tty->termscript, "<MH- %d-%d:%d>", 1022 {
1035 new_pos_X, new_pos_X + nglyphs - 1, new_pos_Y); 1023 struct glyph *glyph = row->glyphs[TEXT_AREA] + start_hpos;
1036 IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos, nglyphs); 1024 int face_id = tty->mouse_highlight.mouse_face_face_id;
1037 if (tty->termscript) 1025 IT_write_glyphs_with_face (f, glyph, nglyphs, face_id);
1038 fputs ("\n", tty->termscript);
1039 new_pos_X = save_x;
1040 new_pos_Y = save_y;
1041 } 1026 }
1027 else
1028 IT_write_glyphs (f, row->glyphs[TEXT_AREA] + start_hpos,
1029 nglyphs);
1030
1031 mouse_on ();
1032 new_pos_X = save_x;
1033 new_pos_Y = save_y;
1042} 1034}
1043 1035
1044static void 1036static void
@@ -1051,7 +1043,7 @@ IT_clear_end_of_line (struct frame *f, int first_unused)
1051 if (new_pos_X >= first_unused || fatal_error_in_progress) 1043 if (new_pos_X >= first_unused || fatal_error_in_progress)
1052 return; 1044 return;
1053 1045
1054 IT_set_face (0); 1046 IT_set_face (f, 0);
1055 i = (j = first_unused - new_pos_X) * 2; 1047 i = (j = first_unused - new_pos_X) * 2;
1056 if (tty->termscript) 1048 if (tty->termscript)
1057 fprintf (tty->termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused); 1049 fprintf (tty->termscript, "<CLR:EOL[%d..%d)>", new_pos_X, first_unused);
@@ -1086,10 +1078,10 @@ IT_clear_screen (struct frame *f)
1086 any valid faces and will abort. Instead, use the initial screen 1078 any valid faces and will abort. Instead, use the initial screen
1087 colors; that should mimic what a Unix tty does, which simply clears 1079 colors; that should mimic what a Unix tty does, which simply clears
1088 the screen with whatever default colors are in use. */ 1080 the screen with whatever default colors are in use. */
1089 if (FACE_FROM_ID_OR_NULL (SELECTED_FRAME (), DEFAULT_FACE_ID) == NULL) 1081 if (FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID) == NULL)
1090 ScreenAttrib = (initial_screen_colors[0] << 4) | initial_screen_colors[1]; 1082 ScreenAttrib = (initial_screen_colors[0] << 4) | initial_screen_colors[1];
1091 else 1083 else
1092 IT_set_face (0); 1084 IT_set_face (f, 0);
1093 mouse_off (); 1085 mouse_off ();
1094 ScreenClear (); 1086 ScreenClear ();
1095 if (screen_virtual_segment) 1087 if (screen_virtual_segment)
@@ -1720,6 +1712,33 @@ IT_set_frame_parameters (struct frame *f, Lisp_Object alist)
1720 store_frame_param (f, prop, val); 1712 store_frame_param (f, prop, val);
1721 } 1713 }
1722 1714
1715 /* If this frame has become a child frame, process its visibility and
1716 a nuumber of other flags. */
1717 if (is_tty_child_frame (f))
1718 {
1719 int x = tty_child_pos_param (f, Qleft, alist, f->left_pos);
1720 int y = tty_child_pos_param (f, Qtop, alist, f->top_pos);
1721 if (x != f->left_pos || y != f->top_pos)
1722 {
1723 f->left_pos = x;
1724 f->top_pos = y;
1725 SET_FRAME_GARBAGED (root_frame (f));
1726 }
1727
1728 int w = tty_child_size_param (f, Qwidth, alist, f->total_cols);
1729 int h = tty_child_size_param (f, Qheight, alist, f->total_lines);
1730 if (w != f->total_cols || h != f->total_lines)
1731 change_frame_size (f, w, h, false, false, false);
1732
1733 Lisp_Object visible = Fassq (Qvisibility, alist);
1734 if (CONSP (visible))
1735 SET_FRAME_VISIBLE (f, !NILP (Fcdr (visible)));
1736
1737 Lisp_Object no_special = Fassq (Qno_special_glyphs, alist);
1738 if (CONSP (no_special))
1739 FRAME_NO_SPECIAL_GLYPHS (f) = !NILP (Fcdr (no_special));
1740 }
1741
1723 /* If they specified "reverse", but not the colors, we need to swap 1742 /* If they specified "reverse", but not the colors, we need to swap
1724 the current frame colors. */ 1743 the current frame colors. */
1725 if (reverse) 1744 if (reverse)
@@ -2861,13 +2880,13 @@ IT_menu_calc_size (XMenu *menu, int *width, int *height)
2861 2880
2862/* Display MENU at (X,Y) using FACES. */ 2881/* Display MENU at (X,Y) using FACES. */
2863 2882
2864#define BUILD_CHAR_GLYPH(GLYPH, CODE, FACE_ID, PADDING_P) \ 2883#define BUILD_CHAR_GLYPH(F, GLYPH, CODE, FACE_ID, PADDING_P) \
2865 do \ 2884 do \
2866 { \ 2885 { \
2867 (GLYPH).type = CHAR_GLYPH; \ 2886 (GLYPH).type = CHAR_GLYPH; \
2868 SET_CHAR_GLYPH (GLYPH, CODE, FACE_ID, PADDING_P); \ 2887 SET_CHAR_GLYPH (F, GLYPH, CODE, FACE_ID, PADDING_P); \
2869 (GLYPH).charpos = -1; \ 2888 (GLYPH).charpos = -1; \
2870 } \ 2889 } \
2871 while (0) 2890 while (0)
2872 2891
2873static void 2892static void
@@ -2891,7 +2910,7 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2891 { 2910 {
2892 int max_width = width + 2; 2911 int max_width = width + 2;
2893 2912
2894 IT_cursor_to (sf, y + i, x); 2913 cursor_to (sf, y + i, x);
2895 enabled 2914 enabled
2896 = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]); 2915 = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
2897 mousehere = (y + i == my && x <= mx && mx < x + max_width); 2916 mousehere = (y + i == my && x <= mx && mx < x + max_width);
@@ -2905,7 +2924,7 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2905 menu_help_itemno = i; 2924 menu_help_itemno = i;
2906 } 2925 }
2907 p = text; 2926 p = text;
2908 BUILD_CHAR_GLYPH (*p, ' ', face, 0); 2927 BUILD_CHAR_GLYPH (sf, *p, ' ', face, 0);
2909 p++; 2928 p++;
2910 for (j = 0, q = menu->text[i]; *q; j++) 2929 for (j = 0, q = menu->text[i]; *q; j++)
2911 { 2930 {
@@ -2913,15 +2932,15 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2913 2932
2914 if (c > 26) 2933 if (c > 26)
2915 { 2934 {
2916 BUILD_CHAR_GLYPH (*p, c, face, 0); 2935 BUILD_CHAR_GLYPH (sf, *p, c, face, 0);
2917 p++; 2936 p++;
2918 } 2937 }
2919 else /* make '^x' */ 2938 else /* make '^x' */
2920 { 2939 {
2921 BUILD_CHAR_GLYPH (*p, '^', face, 0); 2940 BUILD_CHAR_GLYPH (sf, *p, '^', face, 0);
2922 p++; 2941 p++;
2923 j++; 2942 j++;
2924 BUILD_CHAR_GLYPH (*p, c + 64, face, 0); 2943 BUILD_CHAR_GLYPH (sf, *p, c + 64, face, 0);
2925 p++; 2944 p++;
2926 } 2945 }
2927 } 2946 }
@@ -2932,16 +2951,16 @@ IT_menu_display (XMenu *menu, int y, int x, int pn, int *faces, int disp_help)
2932 text[max_width - 1].u.ch = '$'; /* indicate it's truncated */ 2951 text[max_width - 1].u.ch = '$'; /* indicate it's truncated */
2933 } 2952 }
2934 for (; j < max_width - 2; j++, p++) 2953 for (; j < max_width - 2; j++, p++)
2935 BUILD_CHAR_GLYPH (*p, ' ', face, 0); 2954 BUILD_CHAR_GLYPH (sf, *p, ' ', face, 0);
2936 2955
2937 /* 16 is the character code of a character that on DOS terminal 2956 /* 16 is the character code of a character that on DOS terminal
2938 produces a nice-looking right-pointing arrow glyph. */ 2957 produces a nice-looking right-pointing arrow glyph. */
2939 BUILD_CHAR_GLYPH (*p, menu->submenu[i] ? 16 : ' ', face, 0); 2958 BUILD_CHAR_GLYPH (sf, *p, menu->submenu[i] ? 16 : ' ', face, 0);
2940 p++; 2959 p++;
2941 IT_write_glyphs (sf, text, max_width); 2960 IT_write_glyphs (sf, text, max_width);
2942 } 2961 }
2943 IT_update_end (sf); 2962 IT_update_end (sf);
2944 IT_cursor_to (sf, row, col); 2963 cursor_to (sf, row, col);
2945 xfree (text); 2964 xfree (text);
2946} 2965}
2947 2966
diff --git a/src/msdos.h b/src/msdos.h
index b245d9ea761..ad19e4c89c6 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -78,7 +78,6 @@ void syms_of_win16select (void);
78 78
79/* Constants. */ 79/* Constants. */
80#define EINPROGRESS 112 80#define EINPROGRESS 112
81#define ENOTSUP ENOSYS
82/* Gnulib sets O_CLOEXEC to O_NOINHERIT, which gets in the way when we 81/* Gnulib sets O_CLOEXEC to O_NOINHERIT, which gets in the way when we
83 need to redirect standard handles for subprocesses using temporary 82 need to redirect standard handles for subprocesses using temporary
84 files created by mkostemp, see callproc.c. */ 83 files created by mkostemp, see callproc.c. */
diff --git a/src/xdisp.c b/src/xdisp.c
index 08016a6e2a5..91db3a87aae 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -17460,7 +17460,8 @@ redisplay_internal (void)
17460 } 17460 }
17461 17461
17462 retry_frame: 17462 retry_frame:
17463 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf) 17463 if (FRAME_WINDOW_P (f)
17464 || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f) || f == sf)
17464 { 17465 {
17465 /* Only GC scrollbars when we redisplay the whole frame. */ 17466 /* Only GC scrollbars when we redisplay the whole frame. */
17466 bool gcscrollbars = f->redisplay || !REDISPLAY_SOME_P (); 17467 bool gcscrollbars = f->redisplay || !REDISPLAY_SOME_P ();