comparison src/xterm.c @ 6791:7036e4fd549f

(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.
author Richard M. Stallman <rms@gnu.org>
date Sun, 10 Apr 1994 06:06:51 +0000
parents 8fbcee1c2059
children 77ceede38423
comparison
equal deleted inserted replaced
6790:ee8090b47ea6 6791:7036e4fd549f
345 extern Cursor XCreateCursor (); 345 extern Cursor XCreateCursor ();
346 extern FONT_TYPE *XOpenFont (); 346 extern FONT_TYPE *XOpenFont ();
347 347
348 static void flashback (); 348 static void flashback ();
349 static void redraw_previous_char (); 349 static void redraw_previous_char ();
350 static void redraw_following_char ();
350 static unsigned int x_x_to_emacs_modifiers (); 351 static unsigned int x_x_to_emacs_modifiers ();
351 352
352 static void note_mouse_highlight (); 353 static void note_mouse_highlight ();
353 static void clear_mouse_face (); 354 static void clear_mouse_face ();
354 static void show_mouse_face (); 355 static void show_mouse_face ();
539 540
540 /* Display a sequence of N glyphs found at GP. 541 /* Display a sequence of N glyphs found at GP.
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
547 Since the display generation code is responsible for calling 550 Since the display generation code is responsible for calling
548 compute_char_face and compute_glyph_face on everything it puts in 551 compute_char_face and compute_glyph_face on everything it puts in
553 556
554 #if 1 557 #if 1
555 /* This is the multi-face code. */ 558 /* This is the multi-face code. */
556 559
557 static void 560 static void
558 dumpglyphs (f, left, top, gp, n, hl) 561 dumpglyphs (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));
567 register char *cp; /* Steps through buf[]. */ 571 register char *cp; /* Steps through buf[]. */
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 {
574 /* Get the face-code of the next GLYPH. */ 579 /* Get the face-code of the next GLYPH. */
575 int cf, len; 580 int cf, len;
689 } 694 }
690 695
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);
699 732
700 /* We should probably check for XA_UNDERLINE_POSITION and 733 /* We should probably check for XA_UNDERLINE_POSITION and
781 } 814 }
782 815
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
790 && curs_x <= f->phys_cursor_x 823 && curs_x <= f->phys_cursor_x
791 && curs_x + len > f->phys_cursor_x) 824 && curs_x + len > f->phys_cursor_x)
839 CHAR_TO_PIXEL_COL (f, curs_x), 872 CHAR_TO_PIXEL_COL (f, curs_x),
840 CHAR_TO_PIXEL_ROW (f, curs_y), 873 CHAR_TO_PIXEL_ROW (f, curs_y),
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),
848 CHAR_TO_PIXEL_COL (f, curs_x), 881 CHAR_TO_PIXEL_COL (f, curs_x),
849 CHAR_TO_PIXEL_ROW (f, curs_y), 882 CHAR_TO_PIXEL_ROW (f, curs_y),
853 #endif /* ! defined (HAVE_X11) */ 886 #endif /* ! defined (HAVE_X11) */
854 887
855 UNBLOCK_INPUT; 888 UNBLOCK_INPUT;
856 } 889 }
857 890
891 static
892 XTclear_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,
861 in case the character after X overlaps into the one before X. 932 in case the character after X overlaps into the one before X.
862 Call this function with input blocked. */ 933 Call this function with input blocked. */
863 934
864 static void 935 static void
865 redraw_previous_char (f, x, y) 936 redraw_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.
871 Reoutput that character, and the previous character 943 Reoutput that character, and the previous character
872 (in case the previous character overlaps it). */ 944 (in case the previous character overlaps it). */
882 f->display.x->line_height, False); 954 f->display.x->line_height, False);
883 955
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
891 static 963 /* Erase the character (if any) at the position X, Y in frame F,
892 XTclear_frame () 964 then redraw it and the character after it.
893 { 965 This is necessary when we erase endng at X,
894 int mask; 966 in case the character after X overlaps into the one before X.
895 struct frame *f = updating_frame; 967 Call this function with input blocked. */
896 968
897 if (f == 0) 969 static void
898 f = selected_frame; 970 redraw_following_char (f, x, y, highlight_flag)
899 971 FRAME_PTR f;
900 f->phys_cursor_x = -1; /* Cursor not visible. */ 972 int x, y;
901 curs_x = 0; /* Nominal cursor position is top left. */ 973 int highlight_flag;
902 curs_y = 0; 974 {
903 975 int limit = FRAME_CURRENT_GLYPHS (f)->used[y];
904 BLOCK_INPUT; 976 /* Erase the character after the new ones, in case
905 977 what was here before overlaps it.
906 XClear (FRAME_X_WINDOW (f)); 978 Reoutput that character, and the following character
907 979 (in case the following character overlaps it). */
908 /* We have to clear the scroll bars, too. If we have changed 980 if (x < limit
909 colors or something like that, then they should be notified. */ 981 && FRAME_CURRENT_GLYPHS (f)->glyphs[y][x] != SPACEGLYPH)
910 x_scroll_bar_clear (f); 982 {
911 983 int end_x = x + 2;
912 #ifndef HAVE_X11 984 if (end_x > limit)
913 dumpborder (f, 0); 985 end_x = limit;
914 #endif /* HAVE_X11 */ 986 XClearArea (x_current_display, FRAME_X_WINDOW (f),
915 987 CHAR_TO_PIXEL_COL (f, x),
916 XFlushQueue (); 988 CHAR_TO_PIXEL_ROW (f, y),
917 UNBLOCK_INPUT; 989 FONT_WIDTH (f->display.x->font),
918 } 990 f->display.x->line_height, False);
991
992 dumpglyphs (f, CHAR_TO_PIXEL_COL (f, x),
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 */
1001
1002 /* Return 1 if character C in font F extends past its left edge. */
1003
1004 static int
1005 font_char_overlap_left (font, c)
1006 XFontStruct *font;
1007 int c;
1008 {
1009 XCharStruct *s;
1010
1011 /* Find the bounding-box info for C. */
1012 if (font->per_char == 0)
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 }
1043
1044 return (s && s->lbearing < 0);
1045 }
1046
1047 /* Return 1 if character C in font F extends past its right edge. */
1048
1049 static int
1050 font_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);
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
922 /* We use the select system call to do the waiting, so we have to make sure 1095 /* We use the select system call to do the waiting, so we have to make sure
923 it's available. If it isn't, we just won't do visual bells. */ 1096 it's available. If it isn't, we just won't do visual bells. */
1334 1507
1335 dumpglyphs (f, 1508 dumpglyphs (f,
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. */
1343 1516
1344 if (cursor_cleared) 1517 if (cursor_cleared)
1979 2152
1980 /* If we were displaying active text in another window, clear that. */ 2153 /* If we were displaying active text in another window, clear that. */
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;
1990 2165
1991 /* Find which buffer position the mouse corresponds to. */ 2166 /* Find which buffer position the mouse corresponds to. */
2200 CHAR_TO_PIXEL_COL (f, column), 2375 CHAR_TO_PIXEL_COL (f, column),
2201 CHAR_TO_PIXEL_ROW (f, i), 2376 CHAR_TO_PIXEL_ROW (f, i),
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. */
2209 if (cursor_off) 2384 if (cursor_off)
2210 x_display_cursor (f, 1); 2385 x_display_cursor (f, 1);
4273 int highlight; 4448 int highlight;
4274 { 4449 {
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
4281 static void 4456 static void
4282 x_display_bar_cursor (f, on) 4457 x_display_bar_cursor (f, on)
4283 struct frame *f; 4458 struct frame *f;
4381 || f->phys_cursor_x != curs_x 4556 || f->phys_cursor_x != curs_x
4382 || f->phys_cursor_y != curs_y 4557 || f->phys_cursor_y != curs_y
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,
4389 current_glyphs->highlight[f->phys_cursor_y]); 4572 current_glyphs->highlight[f->phys_cursor_y]);
4390 f->phys_cursor_x = -1; 4573 f->phys_cursor_x = -1;
4901 frame_update_line_height (f); 5084 frame_update_line_height (f);
4902 } 5085 }
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;
4910 5093
4911 lispy_name = build_string (fontname); 5094 lispy_name = build_string (fontname);
5049 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows); 5232 pixelheight = CHAR_TO_PIXEL_HEIGHT (f, rows);
5050 5233
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,
5057 but the window manager will get around to dealing with the size 5241 but the window manager will get around to dealing with the size
5058 change request eventually, and we'll hear how it went when the 5242 change request eventually, and we'll hear how it went when the