comparison src/gutter.c @ 406:b8cc9ab3f761 r21-2-33

Import from CVS: tag r21-2-33
author cvs
date Mon, 13 Aug 2007 11:17:09 +0200
parents 2f8bb876ab1d
children 501cfd01ee6d
comparison
equal deleted inserted replaced
405:0e08f63c74d2 406:b8cc9ab3f761
47 Lisp_Object Vdefault_gutter_position; 47 Lisp_Object Vdefault_gutter_position;
48 48
49 Lisp_Object Qgutter_size; 49 Lisp_Object Qgutter_size;
50 Lisp_Object Qgutter_visible; 50 Lisp_Object Qgutter_visible;
51 Lisp_Object Qdefault_gutter_position_changed_hook; 51 Lisp_Object Qdefault_gutter_position_changed_hook;
52
53 static void
54 update_gutter_geometry (struct frame *f, enum gutter_pos pos);
52 55
53 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ 56 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
54 do { \ 57 do { \
55 switch (pos) \ 58 switch (pos) \
56 { \ 59 { \
83 return frame->left_gutter_was_visible; 86 return frame->left_gutter_was_visible;
84 case RIGHT_GUTTER: 87 case RIGHT_GUTTER:
85 return frame->right_gutter_was_visible; 88 return frame->right_gutter_was_visible;
86 default: 89 default:
87 abort (); 90 abort ();
91 return 0; /* To keep the compiler happy */
88 } 92 }
89 } 93 }
90 94
91 #if 0 95 #if 0
92 static Lisp_Object 96 static Lisp_Object
254 struct window* w = XWINDOW (window); 258 struct window* w = XWINDOW (window);
255 int x, y, width, height, ypos; 259 int x, y, width, height, ypos;
256 int line, border_width; 260 int line, border_width;
257 face_index findex; 261 face_index findex;
258 display_line_dynarr* ddla, *cdla; 262 display_line_dynarr* ddla, *cdla;
259 struct display_line *dl; 263 struct display_line *dl = 0;
260 int cdla_len; 264 int cdla_len;
261 265
262 if (!WINDOW_LIVE_P (w)) 266 if (!WINDOW_LIVE_P (w))
263 return; 267 return;
264 268
319 { 323 {
320 Dynarr_length (cdla) = Dynarr_length (ddla); 324 Dynarr_length (cdla) = Dynarr_length (ddla);
321 } 325 }
322 326
323 /* grab coordinates of last line and blank after it. */ 327 /* grab coordinates of last line and blank after it. */
324 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); 328 if (Dynarr_length (ddla) > 0)
325 ypos = dl->ypos + dl->descent - dl->clip; 329 {
330 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
331 ypos = dl->ypos + dl->descent - dl->clip;
332 }
333 else
334 ypos = y;
335
326 redisplay_clear_region (window, findex, x + border_width , ypos, 336 redisplay_clear_region (window, findex, x + border_width , ypos,
327 width - 2 * border_width, height - (ypos - y) - border_width); 337 width - 2 * border_width, height - (ypos - y) - border_width);
338 /* If, for some reason, we have more to display than we have
339 room for, and we are allowed to resize the gutter, then make
340 sure this happens before the next time we try and
341 output. This can happen when face font sizes change. */
342 if (dl && dl->clip > 0 && EQ (w->gutter_size[pos], Qautodetect))
343 {
344 /* #### Ideally we would just mark the specifier as dirty
345 and everything else would "just work". Unfortunately we have
346 two problems with this. One is that the specifier cache
347 won't be recalculated unless the specifier code thinks the
348 cached value has actually changed, even though we have
349 marked the specifier as dirty. Additionally, although doing
350 this results in a gutter size change, we never seem to get
351 back into redisplay so that the frame size can be updated. I
352 think this is because we are already in redisplay and later
353 on the frame will be marked as clean. Thus we also have to
354 force a pending recalculation of the frame size. */
355 w->gutter_size[pos] = Qnil;
356 Fset_specifier_dirty_flag (Vgutter_size[pos]);
357 update_gutter_geometry (f, pos);
358 }
359
328 /* bevel the gutter area if so desired */ 360 /* bevel the gutter area if so desired */
329 if (border_width != 0) 361 if (border_width != 0)
330 { 362 {
331 MAYBE_DEVMETH (d, bevel_area, 363 MAYBE_DEVMETH (d, bevel_area,
332 (w, findex, x, y, width, height, border_width, 364 (w, findex, x, y, width, height, border_width,
466 } 498 }
467 } 499 }
468 500
469 /* We have to change the gutter geometry separately to the gutter 501 /* We have to change the gutter geometry separately to the gutter
470 update since it needs to occur outside of redisplay proper. */ 502 update since it needs to occur outside of redisplay proper. */
503 static void
504 update_gutter_geometry (struct frame *f, enum gutter_pos pos)
505 {
506 /* If the gutter geometry has changed then re-layout the
507 frame. If we are in display there is almost no point in doing
508 anything else since the frame size changes will be delayed
509 until we are out of redisplay proper. */
510 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos])
511 {
512 int width, height;
513 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
514 &width, &height);
515 change_frame_size (f, height, width, 0);
516 }
517
518 /* Mark sizes as up-to-date. */
519 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
520 }
521
471 void 522 void
472 update_frame_gutter_geometry (struct frame *f) 523 update_frame_gutter_geometry (struct frame *f)
473 { 524 {
474 if (f->gutter_changed || f->windows_structure_changed) 525 if (f->gutter_changed || f->windows_structure_changed)
475 { 526 {
479 frame. If we are in display there is almost no point in doing 530 frame. If we are in display there is almost no point in doing
480 anything else since the frame size changes will be delayed 531 anything else since the frame size changes will be delayed
481 until we are out of redisplay proper. */ 532 until we are out of redisplay proper. */
482 GUTTER_POS_LOOP (pos) 533 GUTTER_POS_LOOP (pos)
483 { 534 {
484 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos]) 535 update_gutter_geometry (f, pos);
485 {
486 int width, height;
487 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
488 &width, &height);
489 change_frame_size (f, height, width, 0);
490 break;
491 }
492 }
493
494 GUTTER_POS_LOOP (pos)
495 {
496 /* Mark sizes as up-to-date. */
497 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
498 } 536 }
499 } 537 }
500 } 538 }
501 539
502 void 540 void
555 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width) 593 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
556 return; 594 return;
557 if (((x + width) < g_x) || (x > (g_x + g_width))) 595 if (((x + width) < g_x) || (x > (g_x + g_width)))
558 return; 596 return;
559 597
598 #ifdef DEBUG_WIDGETS
599 printf ("redrawing gutter after expose %d+%d, %dx%d\n",
600 x, y, width, height);
601 #endif
560 /* #### optimize this - redrawing the whole gutter for every expose 602 /* #### optimize this - redrawing the whole gutter for every expose
561 is very expensive. We reset the current display lines because if 603 is very expensive. We reset the current display lines because if
562 they're being exposed they are no longer current. */ 604 they're being exposed they are no longer current. */
563 reset_gutter_display_lines (f); 605 reset_gutter_display_lines (f);
564 606
571 void 613 void
572 redraw_exposed_gutters (struct frame *f, int x, int y, int width, 614 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
573 int height) 615 int height)
574 { 616 {
575 enum gutter_pos pos; 617 enum gutter_pos pos;
618
619 /* We have to be "in display" when we output the gutter - make it
620 so. */
621 hold_frame_size_changes ();
576 GUTTER_POS_LOOP (pos) 622 GUTTER_POS_LOOP (pos)
577 { 623 {
578 if (FRAME_GUTTER_VISIBLE (f, pos)) 624 if (FRAME_GUTTER_VISIBLE (f, pos))
579 redraw_exposed_gutter (f, pos, x, y, width, height); 625 redraw_exposed_gutter (f, pos, x, y, width, height);
580 } 626 }
627 unhold_one_frame_size_changes (f);
581 } 628 }
582 629
583 void 630 void
584 free_frame_gutters (struct frame *f) 631 free_frame_gutters (struct frame *f)
585 { 632 {
1045 DEFSUBR (Fgutter_pixel_width); 1092 DEFSUBR (Fgutter_pixel_width);
1046 DEFSUBR (Fredisplay_gutter_area); 1093 DEFSUBR (Fredisplay_gutter_area);
1047 1094
1048 defsymbol (&Qgutter_size, "gutter-size"); 1095 defsymbol (&Qgutter_size, "gutter-size");
1049 defsymbol (&Qgutter_visible, "gutter-visible"); 1096 defsymbol (&Qgutter_visible, "gutter-visible");
1050 defsymbol (&Qdefault_gutter_position_changed_hook, 1097 defsymbol (&Qdefault_gutter_position_changed_hook,
1051 "default-gutter-position-changed"); 1098 "default-gutter-position-changed-hook");
1052 } 1099 }
1053 1100
1054 void 1101 void
1055 vars_of_gutter (void) 1102 vars_of_gutter (void)
1056 { 1103 {