aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1994-04-10 06:06:51 +0000
committerRichard M. Stallman1994-04-10 06:06:51 +0000
commit0cdd0c9f3e3438b1fe05f1c00f3262ac534898b7 (patch)
tree9b3e76754af9312544e70ec046a9730e5b7cd578 /src
parent8fc2766b6434feb36832e5f150a288c00d3d19bb (diff)
downloademacs-0cdd0c9f3e3438b1fe05f1c00f3262ac534898b7.tar.gz
emacs-0cdd0c9f3e3438b1fe05f1c00f3262ac534898b7.zip
(dumpglyphs): Clear any extra pixel rows below the text.
(x_display_box_cursor): Explicitly clear full height of line. (dumpglyphs): New arg just_foreground. Callers changed. (x_set_window_size): Call XSync. (note_mouse_highlight): Do nothing if buffer has changed.
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c250
1 files changed, 217 insertions, 33 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 70a527a27fe..54880dc843e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -347,6 +347,7 @@ extern FONT_TYPE *XOpenFont ();
347 347
348static void flashback (); 348static void flashback ();
349static void redraw_previous_char (); 349static void redraw_previous_char ();
350static void redraw_following_char ();
350static unsigned int x_x_to_emacs_modifiers (); 351static unsigned int x_x_to_emacs_modifiers ();
351 352
352static void note_mouse_highlight (); 353static void note_mouse_highlight ();
@@ -541,6 +542,8 @@ XTcursor_to (row, col)
541 WINDOW is the x-window to output to. LEFT and TOP are starting coords. 542 WINDOW is the x-window to output to. LEFT and TOP are starting coords.
542 HL is 1 if this text is highlighted, 2 if the cursor is on it, 543 HL is 1 if this text is highlighted, 2 if the cursor is on it,
543 3 if should appear in its mouse-face. 544 3 if should appear in its mouse-face.
545 JUST_FOREGROUND if 1 means draw only the foreground;
546 don't alter the background.
544 547
545 FONT is the default font to use (for glyphs whose font-code is 0). 548 FONT is the default font to use (for glyphs whose font-code is 0).
546 549
@@ -555,12 +558,13 @@ XTcursor_to (row, col)
555/* This is the multi-face code. */ 558/* This is the multi-face code. */
556 559
557static void 560static void
558dumpglyphs (f, left, top, gp, n, hl) 561dumpglyphs (f, left, top, gp, n, hl, just_foreground)
559 struct frame *f; 562 struct frame *f;
560 int left, top; 563 int left, top;
561 register GLYPH *gp; /* Points to first GLYPH. */ 564 register GLYPH *gp; /* Points to first GLYPH. */
562 register int n; /* Number of glyphs to display. */ 565 register int n; /* Number of glyphs to display. */
563 int hl; 566 int hl;
567 int just_foreground;
564{ 568{
565 /* Holds characters to be displayed. */ 569 /* Holds characters to be displayed. */
566 char *buf = (char *) alloca (f->width * sizeof (*buf)); 570 char *buf = (char *) alloca (f->width * sizeof (*buf));
@@ -568,6 +572,7 @@ dumpglyphs (f, left, top, gp, n, hl)
568 register int tlen = GLYPH_TABLE_LENGTH; 572 register int tlen = GLYPH_TABLE_LENGTH;
569 register Lisp_Object *tbase = GLYPH_TABLE_BASE; 573 register Lisp_Object *tbase = GLYPH_TABLE_BASE;
570 Window window = FRAME_X_WINDOW (f); 574 Window window = FRAME_X_WINDOW (f);
575 int orig_left = left;
571 576
572 while (n > 0) 577 while (n > 0)
573 { 578 {
@@ -691,8 +696,36 @@ dumpglyphs (f, left, top, gp, n, hl)
691 if ((int) font == FACE_DEFAULT) 696 if ((int) font == FACE_DEFAULT)
692 font = f->display.x->font; 697 font = f->display.x->font;
693 698
694 XDrawImageString (x_current_display, window, gc, 699 if (just_foreground)
695 left, top + FONT_BASE (font), buf, len); 700 XDrawString (x_current_display, window, gc,
701 left, top + FONT_BASE (font), buf, len);
702 else
703 {
704 XDrawImageString (x_current_display, window, gc,
705 left, top + FONT_BASE (font), buf, len);
706 /* Clear the rest of the line's height. */
707 if (f->display.x->line_height != FONT_HEIGHT (font))
708 XClearArea (x_current_display, window, left,
709 top + FONT_HEIGHT (font),
710 FONT_WIDTH (font) * len,
711 /* This is how many pixels of height
712 we have to clear. */
713 f->display.x->line_height - FONT_HEIGHT (font),
714 False);
715 }
716
717#if 0 /* Doesn't work, because it uses FRAME_CURRENT_GLYPHS,
718 which often is not up to date yet. */
719 if (!just_foreground)
720 {
721 if (left == orig_left)
722 redraw_previous_char (f, PIXEL_TO_CHAR_COL (f, left),
723 PIXEL_TO_CHAR_ROW (f, top), hl == 1);
724 if (n == 0)
725 redraw_following_char (f, PIXEL_TO_CHAR_COL (f, left + len * FONT_WIDTH (font)),
726 PIXEL_TO_CHAR_ROW (f, top), hl == 1);
727 }
728#endif
696 729
697 if (gc_temporary) 730 if (gc_temporary)
698 XFreeGC (x_current_display, gc); 731 XFreeGC (x_current_display, gc);
@@ -783,7 +816,7 @@ XTwrite_glyphs (start, len)
783 dumpglyphs (f, 816 dumpglyphs (f,
784 CHAR_TO_PIXEL_COL (f, curs_x), 817 CHAR_TO_PIXEL_COL (f, curs_x),
785 CHAR_TO_PIXEL_ROW (f, curs_y), 818 CHAR_TO_PIXEL_ROW (f, curs_y),
786 start, len, highlight); 819 start, len, highlight, 0);
787 820
788 /* If we drew on top of the cursor, note that it is turned off. */ 821 /* If we drew on top of the cursor, note that it is turned off. */
789 if (curs_y == f->phys_cursor_y 822 if (curs_y == f->phys_cursor_y
@@ -841,7 +874,7 @@ XTclear_end_of_line (first_unused)
841 FONT_WIDTH (f->display.x->font) * (first_unused - curs_x), 874 FONT_WIDTH (f->display.x->font) * (first_unused - curs_x),
842 f->display.x->line_height, False); 875 f->display.x->line_height, False);
843#if 0 876#if 0
844 redraw_previous_char (f, curs_x, curs_y); 877 redraw_previous_char (f, curs_x, curs_y, highlight);
845#endif 878#endif
846#else /* ! defined (HAVE_X11) */ 879#else /* ! defined (HAVE_X11) */
847 XPixSet (FRAME_X_WINDOW (f), 880 XPixSet (FRAME_X_WINDOW (f),
@@ -855,6 +888,44 @@ XTclear_end_of_line (first_unused)
855 UNBLOCK_INPUT; 888 UNBLOCK_INPUT;
856} 889}
857 890
891static
892XTclear_frame ()
893{
894 int mask;
895 struct frame *f = updating_frame;
896
897 if (f == 0)
898 f = selected_frame;
899
900 f->phys_cursor_x = -1; /* Cursor not visible. */
901 curs_x = 0; /* Nominal cursor position is top left. */
902 curs_y = 0;
903
904 BLOCK_INPUT;
905
906 XClear (FRAME_X_WINDOW (f));
907
908 /* We have to clear the scroll bars, too. If we have changed
909 colors or something like that, then they should be notified. */
910 x_scroll_bar_clear (f);
911
912#ifndef HAVE_X11
913 dumpborder (f, 0);
914#endif /* HAVE_X11 */
915
916 XFlushQueue ();
917 UNBLOCK_INPUT;
918}
919
920#if 0
921/* This currently does not work because FRAME_CURRENT_GLYPHS doesn't
922 always contain the right glyphs to use.
923
924 It also needs to be changed to look at the details of the font and
925 see whether there is really overlap, and do nothing when there is
926 not. This can use font_char_overlap_left and font_char_overlap_right,
927 but just how to use them is not clear. */
928
858/* Erase the character (if any) at the position just before X, Y in frame F, 929/* Erase the character (if any) at the position just before X, Y in frame F,
859 then redraw it and the character before it. 930 then redraw it and the character before it.
860 This is necessary when we erase starting at X, 931 This is necessary when we erase starting at X,
@@ -862,9 +933,10 @@ XTclear_end_of_line (first_unused)
862 Call this function with input blocked. */ 933 Call this function with input blocked. */
863 934
864static void 935static void
865redraw_previous_char (f, x, y) 936redraw_previous_char (f, x, y, highlight_flag)
866 FRAME_PTR f; 937 FRAME_PTR f;
867 int x, y; 938 int x, y;
939 int highlight_flag;
868{ 940{
869 /* Erase the character before the new ones, in case 941 /* Erase the character before the new ones, in case
870 what was here before overlaps it. 942 what was here before overlaps it.
@@ -884,38 +956,139 @@ redraw_previous_char (f, x, y)
884 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x), 956 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, start_x),
885 CHAR_TO_PIXEL_ROW (f, y), 957 CHAR_TO_PIXEL_ROW (f, y),
886 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x], 958 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][start_x],
887 x - start_x, highlight); 959 x - start_x, highlight_flag, 1);
888 } 960 }
889} 961}
890 962
891static 963/* Erase the character (if any) at the position X, Y in frame F,
892XTclear_frame () 964 then redraw it and the character after it.
965 This is necessary when we erase endng at X,
966 in case the character after X overlaps into the one before X.
967 Call this function with input blocked. */
968
969static void
970redraw_following_char (f, x, y, highlight_flag)
971 FRAME_PTR f;
972 int x, y;
973 int highlight_flag;
893{ 974{
894 int mask; 975 int limit = FRAME_CURRENT_GLYPHS (f)->used[y];
895 struct frame *f = updating_frame; 976 /* Erase the character after the new ones, in case
977 what was here before overlaps it.
978 Reoutput that character, and the following character
979 (in case the following character overlaps it). */
980 if (x < limit
981 && FRAME_CURRENT_GLYPHS (f)->glyphs[y][x] != SPACEGLYPH)
982 {
983 int end_x = x + 2;
984 if (end_x > limit)
985 end_x = limit;
986 XClearArea (x_current_display, FRAME_X_WINDOW (f),
987 CHAR_TO_PIXEL_COL (f, x),
988 CHAR_TO_PIXEL_ROW (f, y),
989 FONT_WIDTH (f->display.x->font),
990 f->display.x->line_height, False);
896 991
897 if (f == 0) 992 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x),
898 f = selected_frame; 993 CHAR_TO_PIXEL_ROW (f, y),
994 &FRAME_CURRENT_GLYPHS (f)->glyphs[y][x],
995 end_x - x, highlight_flag, 1);
996 }
997}
998#endif /* 0 */
999
1000#if 0 /* Not in use yet */
899 1001
900 f->phys_cursor_x = -1; /* Cursor not visible. */ 1002/* Return 1 if character C in font F extends past its left edge. */
901 curs_x = 0; /* Nominal cursor position is top left. */
902 curs_y = 0;
903
904 BLOCK_INPUT;
905 1003
906 XClear (FRAME_X_WINDOW (f)); 1004static int
1005font_char_overlap_left (font, c)
1006 XFontStruct *font;
1007 int c;
1008{
1009 XCharStruct *s;
907 1010
908 /* We have to clear the scroll bars, too. If we have changed 1011 /* Find the bounding-box info for C. */
909 colors or something like that, then they should be notified. */ 1012 if (font->per_char == 0)
910 x_scroll_bar_clear (f); 1013 s = &font->max_bounds;
1014 else
1015 {
1016 int rowlen = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
1017 int row, within;
1018
1019 /* Decode char into row number (byte 1) and code within row (byte 2). */
1020 row = c >> 8;
1021 within = c & 0177;
1022 if (!(within >= font->min_char_or_byte2
1023 && within <= font->max_char_or_byte2
1024 && row >= font->min_byte1
1025 && row <= font->max_byte1))
1026 {
1027 /* If char is out of range, try the font's default char instead. */
1028 c = font->default_char;
1029 row = c >> (INTBITS - 8);
1030 within = c & 0177;
1031 }
1032 if (!(within >= font->min_char_or_byte2
1033 && within <= font->max_char_or_byte2
1034 && row >= font->min_byte1
1035 && row <= font->max_byte1))
1036 /* Still out of range means this char does not overlap. */
1037 return 0;
1038 else
1039 /* We found the info for this char. */
1040 s = (font->per_char + (within - font->min_char_or_byte2)
1041 + row * rowlen);
1042 }
911 1043
912#ifndef HAVE_X11 1044 return (s && s->lbearing < 0);
913 dumpborder (f, 0); 1045}
914#endif /* HAVE_X11 */
915 1046
916 XFlushQueue (); 1047/* Return 1 if character C in font F extends past its right edge. */
917 UNBLOCK_INPUT; 1048
1049static int
1050font_char_overlap_right (font, c)
1051 XFontStruct *font;
1052 int c;
1053{
1054 XCharStruct *s;
1055
1056 /* Find the bounding-box info for C. */
1057 if (font->per_char == 0)
1058 s = &font->max_bounds;
1059 else
1060 {
1061 int rowlen = font->max_char_or_byte2 - font->min_char_or_byte2 + 1;
1062 int row, within;
1063
1064 /* Decode char into row number (byte 1) and code within row (byte 2). */
1065 row = c >> 8;
1066 within = c & 0177;
1067 if (!(within >= font->min_char_or_byte2
1068 && within <= font->max_char_or_byte2
1069 && row >= font->min_byte1
1070 && row <= font->max_byte1))
1071 {
1072 /* If char is out of range, try the font's default char instead. */
1073 c = font->default_char;
1074 row = c >> (INTBITS - 8);
1075 within = c & 0177;
1076 }
1077 if (!(within >= font->min_char_or_byte2
1078 && within <= font->max_char_or_byte2
1079 && row >= font->min_byte1
1080 && row <= font->max_byte1))
1081 /* Still out of range means this char does not overlap. */
1082 return 0;
1083 else
1084 /* We found the info for this char. */
1085 s = (font->per_char + (within - font->min_char_or_byte2)
1086 + row * rowlen);
1087 }
1088
1089 return (s && s->rbearing >= s->width);
918} 1090}
1091#endif /* 0 */
919 1092
920/* Invert the middle quarter of the frame for .15 sec. */ 1093/* Invert the middle quarter of the frame for .15 sec. */
921 1094
@@ -1336,7 +1509,7 @@ dumprectangle (f, left, top, cols, rows)
1336 CHAR_TO_PIXEL_COL (f, left), 1509 CHAR_TO_PIXEL_COL (f, left),
1337 CHAR_TO_PIXEL_ROW (f, y), 1510 CHAR_TO_PIXEL_ROW (f, y),
1338 line, min (cols, active_frame->used[y] - left), 1511 line, min (cols, active_frame->used[y] - left),
1339 active_frame->highlight[y]); 1512 active_frame->highlight[y], 0);
1340 } 1513 }
1341 1514
1342 /* Turn the cursor on if we turned it off. */ 1515 /* Turn the cursor on if we turned it off. */
@@ -1981,9 +2154,11 @@ note_mouse_highlight (f, x, y)
1981 if (! EQ (window, mouse_face_window)) 2154 if (! EQ (window, mouse_face_window))
1982 clear_mouse_face (); 2155 clear_mouse_face ();
1983 2156
1984 /* Are we in a window whose display is up to date? */ 2157 /* Are we in a window whose display is up to date?
2158 And verify the buffer's text has not changed. */
1985 if (WINDOWP (window) && portion == 0 2159 if (WINDOWP (window) && portion == 0
1986 && EQ (w->window_end_valid, w->buffer)) 2160 && EQ (w->window_end_valid, w->buffer)
2161 && w->last_modified == BUF_MODIFF (XBUFFER (w->buffer)))
1987 { 2162 {
1988 int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row]; 2163 int *ptr = FRAME_CURRENT_GLYPHS (f)->charstarts[row];
1989 int i, pos; 2164 int i, pos;
@@ -2202,7 +2377,7 @@ show_mouse_face (hl)
2202 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column, 2377 FRAME_CURRENT_GLYPHS (f)->glyphs[i] + column,
2203 endcolumn - column, 2378 endcolumn - column,
2204 /* Highlight with mouse face if hl > 0. */ 2379 /* Highlight with mouse face if hl > 0. */
2205 hl > 0 ? 3 : 0); 2380 hl > 0 ? 3 : 0, 0);
2206 } 2381 }
2207 2382
2208 /* If we turned the cursor off, turn it back on. */ 2383 /* If we turned the cursor off, turn it back on. */
@@ -4275,7 +4450,7 @@ x_draw_single_glyph (f, row, column, glyph, highlight)
4275 dumpglyphs (f, 4450 dumpglyphs (f,
4276 CHAR_TO_PIXEL_COL (f, column), 4451 CHAR_TO_PIXEL_COL (f, column),
4277 CHAR_TO_PIXEL_ROW (f, row), 4452 CHAR_TO_PIXEL_ROW (f, row),
4278 &glyph, 1, highlight); 4453 &glyph, 1, highlight, 0);
4279} 4454}
4280 4455
4281static void 4456static void
@@ -4383,6 +4558,14 @@ x_display_box_cursor (f, on)
4383 || (f->display.x->current_cursor != hollow_box_cursor 4558 || (f->display.x->current_cursor != hollow_box_cursor
4384 && (f != x_highlight_frame)))) 4559 && (f != x_highlight_frame))))
4385 { 4560 {
4561 /* If the font is not as tall as a whole line,
4562 we must explicitly clear the line's whole height. */
4563 if (FONT_HEIGHT (f->display.x->font) != f->display.x->line_height)
4564 XClearArea (x_current_display, FRAME_X_WINDOW (f),
4565 CHAR_TO_PIXEL_COL (f, f->phys_cursor_x),
4566 CHAR_TO_PIXEL_ROW (f, f->phys_cursor_y),
4567 FONT_WIDTH (f->display.x->font),
4568 f->display.x->line_height, False);
4386 /* Erase the cursor by redrawing the character underneath it. */ 4569 /* Erase the cursor by redrawing the character underneath it. */
4387 x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x, 4570 x_draw_single_glyph (f, f->phys_cursor_y, f->phys_cursor_x,
4388 f->phys_cursor_glyph, 4571 f->phys_cursor_glyph,
@@ -4903,7 +5086,7 @@ x_new_font (f, fontname)
4903 else 5086 else
4904 /* If we are setting a new frame's font for the first time, 5087 /* If we are setting a new frame's font for the first time,
4905 there are no faces yet, so this font's height is the line height. */ 5088 there are no faces yet, so this font's height is the line height. */
4906 f->display.x->line_height = FONT_HEIGHT (f); 5089 f->display.x->line_height = FONT_HEIGHT (f->display.x->font);
4907 5090
4908 { 5091 {
4909 Lisp_Object lispy_name; 5092 Lisp_Object lispy_name;
@@ -5051,6 +5234,7 @@ x_set_window_size (f, change_gravity, cols, rows)
5051#ifdef HAVE_X11 5234#ifdef HAVE_X11
5052 x_wm_set_size_hint (f, 0, change_gravity, 0, 0); 5235 x_wm_set_size_hint (f, 0, change_gravity, 0, 0);
5053#endif /* ! defined (HAVE_X11) */ 5236#endif /* ! defined (HAVE_X11) */
5237 XSync (x_current_display, False);
5054 XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight); 5238 XChangeWindowSize (FRAME_X_WINDOW (f), pixelwidth, pixelheight);
5055 5239
5056 /* Now, strictly speaking, we can't be sure that this is accurate, 5240 /* Now, strictly speaking, we can't be sure that this is accurate,