comparison src/xterm.c @ 40207:7c57640154a5

(x_draw_glyphs): Remove parameters READ_START and REAL_END. Notice if cursor gets overwritten. (notice_overwritten_cursor): Take X positions as parameters. (x_draw_phys_cursor_glyph): Save state of w->phys_cursor_on_p around call to x_draw_glyphs.
author Gerd Moellmann <gerd@gnu.org>
date Tue, 23 Oct 2001 12:03:47 +0000
parents d505fb8b523f
children 9175d0c189f4
comparison
equal deleted inserted replaced
40206:7a929b1e1f77 40207:7c57640154a5
2504 struct glyph_row *, 2504 struct glyph_row *,
2505 enum glyph_row_area, int, 2505 enum glyph_row_area, int,
2506 enum draw_glyphs_face)); 2506 enum draw_glyphs_face));
2507 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, 2507 static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *,
2508 enum glyph_row_area, int, int, 2508 enum glyph_row_area, int, int,
2509 enum draw_glyphs_face, int *, int *, int)); 2509 enum draw_glyphs_face, int));
2510 static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); 2510 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2511 static void x_set_glyph_string_gc P_ ((struct glyph_string *)); 2511 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2512 static void x_draw_glyph_string_background P_ ((struct glyph_string *, 2512 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2513 int)); 2513 int));
2514 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); 2514 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
5016 DRAW_MOUSE_FACE draw in mouse face. 5016 DRAW_MOUSE_FACE draw in mouse face.
5017 DRAW_INVERSE_VIDEO draw in mode line face 5017 DRAW_INVERSE_VIDEO draw in mode line face
5018 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it 5018 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
5019 DRAW_IMAGE_RAISED draw an image with a raised relief around it 5019 DRAW_IMAGE_RAISED draw an image with a raised relief around it
5020 5020
5021 If REAL_START is non-null, return in *REAL_START the real starting
5022 position for display. This can be different from START in case
5023 overlapping glyphs must be displayed. If REAL_END is non-null,
5024 return in *REAL_END the real end position for display. This can be
5025 different from END in case overlapping glyphs must be displayed.
5026
5027 If OVERLAPS_P is non-zero, draw only the foreground of characters 5021 If OVERLAPS_P is non-zero, draw only the foreground of characters
5028 and clip to the physical height of ROW. 5022 and clip to the physical height of ROW.
5029 5023
5030 Value is the x-position reached, relative to AREA of W. */ 5024 Value is the x-position reached, relative to AREA of W. */
5031 5025
5032 static int 5026 static int
5033 x_draw_glyphs (w, x, row, area, start, end, hl, real_start, real_end, 5027 x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
5034 overlaps_p)
5035 struct window *w; 5028 struct window *w;
5036 int x; 5029 int x;
5037 struct glyph_row *row; 5030 struct glyph_row *row;
5038 enum glyph_row_area area; 5031 enum glyph_row_area area;
5039 int start, end; 5032 int start, end;
5040 enum draw_glyphs_face hl; 5033 enum draw_glyphs_face hl;
5041 int *real_start, *real_end;
5042 int overlaps_p; 5034 int overlaps_p;
5043 { 5035 {
5044 struct glyph_string *head, *tail; 5036 struct glyph_string *head, *tail;
5045 struct glyph_string *s; 5037 struct glyph_string *s;
5046 int last_x, area_width; 5038 int last_x, area_width;
5049 5041
5050 /* Let's rather be paranoid than getting a SEGV. */ 5042 /* Let's rather be paranoid than getting a SEGV. */
5051 end = min (end, row->used[area]); 5043 end = min (end, row->used[area]);
5052 start = max (0, start); 5044 start = max (0, start);
5053 start = min (end, start); 5045 start = min (end, start);
5054 if (real_start)
5055 *real_start = start;
5056 if (real_end)
5057 *real_end = end;
5058 5046
5059 /* Translate X to frame coordinates. Set last_x to the right 5047 /* Translate X to frame coordinates. Set last_x to the right
5060 end of the drawing area. */ 5048 end of the drawing area. */
5061 if (row->full_width_p) 5049 if (row->full_width_p)
5062 { 5050 {
5124 j = i; 5112 j = i;
5125 BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t, 5113 BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t,
5126 DRAW_NORMAL_TEXT, dummy_x, last_x, 5114 DRAW_NORMAL_TEXT, dummy_x, last_x,
5127 overlaps_p); 5115 overlaps_p);
5128 start = i; 5116 start = i;
5129 if (real_start)
5130 *real_start = start;
5131 x_compute_overhangs_and_x (t, head->x, 1); 5117 x_compute_overhangs_and_x (t, head->x, 1);
5132 x_prepend_glyph_string_lists (&head, &tail, h, t); 5118 x_prepend_glyph_string_lists (&head, &tail, h, t);
5133 } 5119 }
5134 5120
5135 /* Prepend glyph strings for glyphs in front of the first glyph 5121 /* Prepend glyph strings for glyphs in front of the first glyph
5145 BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t, 5131 BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t,
5146 DRAW_NORMAL_TEXT, dummy_x, last_x, 5132 DRAW_NORMAL_TEXT, dummy_x, last_x,
5147 overlaps_p); 5133 overlaps_p);
5148 for (s = h; s; s = s->next) 5134 for (s = h; s; s = s->next)
5149 s->background_filled_p = 1; 5135 s->background_filled_p = 1;
5150 if (real_start)
5151 *real_start = i;
5152 x_compute_overhangs_and_x (t, head->x, 1); 5136 x_compute_overhangs_and_x (t, head->x, 1);
5153 x_prepend_glyph_string_lists (&head, &tail, h, t); 5137 x_prepend_glyph_string_lists (&head, &tail, h, t);
5154 } 5138 }
5155 5139
5156 /* Append glyphs strings for glyphs following the last glyph 5140 /* Append glyphs strings for glyphs following the last glyph
5163 BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t, 5147 BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t,
5164 DRAW_NORMAL_TEXT, x, last_x, 5148 DRAW_NORMAL_TEXT, x, last_x,
5165 overlaps_p); 5149 overlaps_p);
5166 x_compute_overhangs_and_x (h, tail->x + tail->width, 0); 5150 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
5167 x_append_glyph_string_lists (&head, &tail, h, t); 5151 x_append_glyph_string_lists (&head, &tail, h, t);
5168 if (real_end)
5169 *real_end = i;
5170 } 5152 }
5171 5153
5172 /* Append glyph strings for glyphs following the last glyph 5154 /* Append glyph strings for glyphs following the last glyph
5173 string tail that overwrite tail. The foreground of such 5155 string tail that overwrite tail. The foreground of such
5174 glyphs has to be drawn because it writes into the background 5156 glyphs has to be drawn because it writes into the background
5182 overlaps_p); 5164 overlaps_p);
5183 for (s = h; s; s = s->next) 5165 for (s = h; s; s = s->next)
5184 s->background_filled_p = 1; 5166 s->background_filled_p = 1;
5185 x_compute_overhangs_and_x (h, tail->x + tail->width, 0); 5167 x_compute_overhangs_and_x (h, tail->x + tail->width, 0);
5186 x_append_glyph_string_lists (&head, &tail, h, t); 5168 x_append_glyph_string_lists (&head, &tail, h, t);
5187 if (real_end)
5188 *real_end = i;
5189 } 5169 }
5190 } 5170 }
5191 5171
5192 /* Draw all strings. */ 5172 /* Draw all strings. */
5193 for (s = head; s; s = s->next) 5173 for (s = head; s; s = s->next)
5194 x_draw_glyph_string (s); 5174 x_draw_glyph_string (s);
5175
5176 if (area == TEXT_AREA)
5177 {
5178 int x0 = head ? head->x : x;
5179 int x1 = tail ? tail->x + tail->background_width : x;
5180
5181 x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0);
5182 x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1);
5183
5184 if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0)
5185 {
5186 int left_area_width = window_box_width (w, LEFT_MARGIN_AREA);
5187 x0 -= left_area_width;
5188 x1 -= left_area_width;
5189 }
5190
5191 notice_overwritten_cursor (w, x0, x1);
5192 }
5195 5193
5196 /* Value is the x-position up to which drawn, relative to AREA of W. 5194 /* Value is the x-position up to which drawn, relative to AREA of W.
5197 This doesn't include parts drawn because of overhangs. */ 5195 This doesn't include parts drawn because of overhangs. */
5198 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); 5196 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
5199 if (!row->full_width_p) 5197 if (!row->full_width_p)
5200 { 5198 {
5201 if (area > LEFT_MARGIN_AREA) 5199 if (area > LEFT_MARGIN_AREA && XFASTINT (w->left_margin_width) != 0)
5202 x_reached -= window_box_width (w, LEFT_MARGIN_AREA); 5200 x_reached -= window_box_width (w, LEFT_MARGIN_AREA);
5203 if (area > TEXT_AREA) 5201 if (area > TEXT_AREA)
5204 x_reached -= window_box_width (w, TEXT_AREA); 5202 x_reached -= window_box_width (w, TEXT_AREA);
5205 } 5203 }
5206 5204
5241 } 5239 }
5242 while (i < row->used[area] 5240 while (i < row->used[area]
5243 && row->glyphs[area][i].overlaps_vertically_p); 5241 && row->glyphs[area][i].overlaps_vertically_p);
5244 5242
5245 x_draw_glyphs (w, start_x, row, area, start, i, 5243 x_draw_glyphs (w, start_x, row, area, start, i,
5246 DRAW_NORMAL_TEXT, NULL, NULL, 1); 5244 DRAW_NORMAL_TEXT, 1);
5247 } 5245 }
5248 else 5246 else
5249 { 5247 {
5250 x += row->glyphs[area][i].pixel_width; 5248 x += row->glyphs[area][i].pixel_width;
5251 ++i; 5249 ++i;
5265 static void 5263 static void
5266 x_write_glyphs (start, len) 5264 x_write_glyphs (start, len)
5267 struct glyph *start; 5265 struct glyph *start;
5268 int len; 5266 int len;
5269 { 5267 {
5270 int x, hpos, real_start, real_end; 5268 int x, hpos;
5271 5269
5272 xassert (updated_window && updated_row); 5270 xassert (updated_window && updated_row);
5273 BLOCK_INPUT; 5271 BLOCK_INPUT;
5274 5272
5275 /* Write glyphs. */ 5273 /* Write glyphs. */
5276 5274
5277 hpos = start - updated_row->glyphs[updated_area]; 5275 hpos = start - updated_row->glyphs[updated_area];
5278 x = x_draw_glyphs (updated_window, output_cursor.x, 5276 x = x_draw_glyphs (updated_window, output_cursor.x,
5279 updated_row, updated_area, 5277 updated_row, updated_area,
5280 hpos, hpos + len, 5278 hpos, hpos + len,
5281 DRAW_NORMAL_TEXT, 5279 DRAW_NORMAL_TEXT, 0);
5282 &real_start, &real_end, 0);
5283
5284 /* If we drew over the cursor, note that it is not visible any more. */
5285 notice_overwritten_cursor (updated_window, real_start,
5286 real_end - real_start);
5287 5280
5288 UNBLOCK_INPUT; 5281 UNBLOCK_INPUT;
5289 5282
5290 /* Advance the output cursor. */ 5283 /* Advance the output cursor. */
5291 output_cursor.hpos += len; 5284 output_cursor.hpos += len;
5336 frame_x + shift_by_width, frame_y); 5329 frame_x + shift_by_width, frame_y);
5337 5330
5338 /* Write the glyphs. */ 5331 /* Write the glyphs. */
5339 hpos = start - row->glyphs[updated_area]; 5332 hpos = start - row->glyphs[updated_area];
5340 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len, 5333 x_draw_glyphs (w, output_cursor.x, row, updated_area, hpos, hpos + len,
5341 DRAW_NORMAL_TEXT, &real_start, &real_end, 0); 5334 DRAW_NORMAL_TEXT, 0);
5342 notice_overwritten_cursor (w, real_start, real_end - real_start);
5343 5335
5344 /* Advance the output cursor. */ 5336 /* Advance the output cursor. */
5345 output_cursor.hpos += len; 5337 output_cursor.hpos += len;
5346 output_cursor.x += shift_by_width; 5338 output_cursor.x += shift_by_width;
5347 UNBLOCK_INPUT; 5339 UNBLOCK_INPUT;
5416 5408
5417 to_y = min (max_y, output_cursor.y + updated_row->height); 5409 to_y = min (max_y, output_cursor.y + updated_row->height);
5418 5410
5419 /* Notice if the cursor will be cleared by this operation. */ 5411 /* Notice if the cursor will be cleared by this operation. */
5420 if (!updated_row->full_width_p) 5412 if (!updated_row->full_width_p)
5421 notice_overwritten_cursor (w, output_cursor.hpos, -1); 5413 notice_overwritten_cursor (w, output_cursor.x, -1);
5422 5414
5423 from_x = output_cursor.x; 5415 from_x = output_cursor.x;
5424 5416
5425 /* Translate to frame coordinates. */ 5417 /* Translate to frame coordinates. */
5426 if (updated_row->full_width_p) 5418 if (updated_row->full_width_p)
5905 int first_x, start_x, x; 5897 int first_x, start_x, x;
5906 5898
5907 if (area == TEXT_AREA && row->fill_line_p) 5899 if (area == TEXT_AREA && row->fill_line_p)
5908 /* If row extends face to end of line write the whole line. */ 5900 /* If row extends face to end of line write the whole line. */
5909 x_draw_glyphs (w, 0, row, area, 0, row->used[area], 5901 x_draw_glyphs (w, 0, row, area, 0, row->used[area],
5910 DRAW_NORMAL_TEXT, NULL, NULL, 0); 5902 DRAW_NORMAL_TEXT, 0);
5911 else 5903 else
5912 { 5904 {
5913 /* Set START_X to the window-relative start position for drawing glyphs of 5905 /* Set START_X to the window-relative start position for drawing glyphs of
5914 AREA. The first glyph of the text area can be partially visible. 5906 AREA. The first glyph of the text area can be partially visible.
5915 The first glyphs of other areas cannot. */ 5907 The first glyphs of other areas cannot. */
5943 /* Repaint. */ 5935 /* Repaint. */
5944 if (last > first) 5936 if (last > first)
5945 x_draw_glyphs (w, first_x - start_x, row, area, 5937 x_draw_glyphs (w, first_x - start_x, row, area,
5946 first - row->glyphs[area], 5938 first - row->glyphs[area],
5947 last - row->glyphs[area], 5939 last - row->glyphs[area],
5948 DRAW_NORMAL_TEXT, 5940 DRAW_NORMAL_TEXT, 0);
5949 NULL, NULL, 0);
5950 } 5941 }
5951 } 5942 }
5952 5943
5953 5944
5954 /* Redraw the parts of the glyph row ROW on window W intersecting 5945 /* Redraw the parts of the glyph row ROW on window W intersecting
5963 { 5954 {
5964 xassert (row->enabled_p); 5955 xassert (row->enabled_p);
5965 5956
5966 if (row->mode_line_p || w->pseudo_window_p) 5957 if (row->mode_line_p || w->pseudo_window_p)
5967 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA], 5958 x_draw_glyphs (w, 0, row, TEXT_AREA, 0, row->used[TEXT_AREA],
5968 DRAW_NORMAL_TEXT, NULL, NULL, 0); 5959 DRAW_NORMAL_TEXT, 0);
5969 else 5960 else
5970 { 5961 {
5971 if (row->used[LEFT_MARGIN_AREA]) 5962 if (row->used[LEFT_MARGIN_AREA])
5972 expose_area (w, row, r, LEFT_MARGIN_AREA); 5963 expose_area (w, row, r, LEFT_MARGIN_AREA);
5973 if (row->used[TEXT_AREA]) 5964 if (row->used[TEXT_AREA])
7789 } 7780 }
7790 7781
7791 if (end_hpos > start_hpos) 7782 if (end_hpos > start_hpos)
7792 { 7783 {
7793 x_draw_glyphs (w, start_x, row, TEXT_AREA, 7784 x_draw_glyphs (w, start_x, row, TEXT_AREA,
7794 start_hpos, end_hpos, draw, NULL, NULL, 0); 7785 start_hpos, end_hpos, draw, 0);
7795 row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED; 7786 row->mouse_face_p = draw == DRAW_MOUSE_FACE || DRAW_IMAGE_RAISED;
7796 } 7787 }
7797 } 7788 }
7798 7789
7799 /* If we turned the cursor off, turn it back on. */ 7790 /* If we turned the cursor off, turn it back on. */
11094 /*********************************************************************** 11085 /***********************************************************************
11095 Text Cursor 11086 Text Cursor
11096 ***********************************************************************/ 11087 ***********************************************************************/
11097 11088
11098 /* Notice if the text cursor of window W has been overwritten by a 11089 /* Notice if the text cursor of window W has been overwritten by a
11099 drawing operation that outputs N glyphs starting at HPOS in the 11090 drawing operation that outputs N glyphs starting at START_X and
11100 line given by output_cursor.vpos. 11091 ending at END_X in the line given by output_cursor.vpos.
11101 11092 Coordinates are area-relative. END_X < 0 means means all the rest
11102 N < 0 means all the rest of the line after HPOS has been 11093 of the line after START_X has been written. */
11103 written. */
11104 11094
11105 static void 11095 static void
11106 notice_overwritten_cursor (w, hpos, n) 11096 notice_overwritten_cursor (w, start_x, end_x)
11107 struct window *w; 11097 struct window *w;
11108 int hpos, n; 11098 int start_x, end_x;
11109 { 11099 {
11110 if (updated_area == TEXT_AREA 11100 if (updated_area == TEXT_AREA
11101 && w->phys_cursor_on_p
11111 && output_cursor.vpos == w->phys_cursor.vpos 11102 && output_cursor.vpos == w->phys_cursor.vpos
11112 && output_cursor.x <= w->phys_cursor.x 11103 && start_x <= w->phys_cursor.x
11113 && w->phys_cursor_on_p) 11104 && end_x > w->phys_cursor.x)
11114 { 11105 w->phys_cursor_on_p = 0;
11115 if (n < 0)
11116 w->phys_cursor_on_p = 0;
11117 else
11118 {
11119 /* It depends on the width of the N glyphs written at HPOS
11120 if the cursor has been overwritten or not. */
11121 struct glyph *glyph = &updated_row->glyphs[TEXT_AREA][hpos];
11122 struct glyph *end = glyph + n;
11123 int width = 0;
11124
11125 for (; glyph < end; ++glyph)
11126 width += glyph->pixel_width;
11127
11128 if (output_cursor.x + width > w->phys_cursor.x)
11129 w->phys_cursor_on_p = 0;
11130 }
11131 }
11132 } 11106 }
11133 11107
11134 11108
11135 /* Set clipping for output in glyph row ROW. W is the window in which 11109 /* Set clipping for output in glyph row ROW. W is the window in which
11136 we operate. GC is the graphics context to set clipping in. 11110 we operate. GC is the graphics context to set clipping in.
11322 /* If cursor hpos is out of bounds, don't draw garbage. This can 11296 /* If cursor hpos is out of bounds, don't draw garbage. This can
11323 happen in mini-buffer windows when switching between echo area 11297 happen in mini-buffer windows when switching between echo area
11324 glyphs and mini-buffer. */ 11298 glyphs and mini-buffer. */
11325 if (w->phys_cursor.hpos < row->used[TEXT_AREA]) 11299 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
11326 { 11300 {
11301 int on_p = w->phys_cursor_on_p;
11302
11327 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, 11303 x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
11328 w->phys_cursor.hpos, w->phys_cursor.hpos + 1, 11304 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
11329 hl, 0, 0, 0); 11305 hl, 0);
11306 w->phys_cursor_on_p = on_p;
11330 11307
11331 /* When we erase the cursor, and ROW is overlapped by other 11308 /* When we erase the cursor, and ROW is overlapped by other
11332 rows, make sure that these overlapping parts of other rows 11309 rows, make sure that these overlapping parts of other rows
11333 are redrawn. */ 11310 are redrawn. */
11334 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p) 11311 if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)