comparison src/gutter.c @ 424:11054d720c21 r21-2-20

Import from CVS: tag r21-2-20
author cvs
date Mon, 13 Aug 2007 11:26:11 +0200
parents 95016f13131a
children
comparison
equal deleted inserted replaced
423:28d9c139be4c 424:11054d720c21
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */ 19 Boston, MA 02111-1307, USA. */
20 20
21 /* Synched up with: Not in FSF. */ 21 /* Synched up with: Not in FSF. */
22 22
23 /* Specifers ripped-off from toolbar.c */ 23 /* written by Andy Piper <andy@xemacs.org> with specifiers partially
24 ripped-off from toolbar.c */
24 25
25 #include <config.h> 26 #include <config.h>
26 #include "lisp.h" 27 #include "lisp.h"
27 28
28 #include "buffer.h" 29 #include "buffer.h"
43 Lisp_Object Vdefault_gutter_width, Vdefault_gutter_height; 44 Lisp_Object Vdefault_gutter_width, Vdefault_gutter_height;
44 Lisp_Object Vdefault_gutter_border_width; 45 Lisp_Object Vdefault_gutter_border_width;
45 46
46 Lisp_Object Vdefault_gutter_position; 47 Lisp_Object Vdefault_gutter_position;
47 48
48 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ 49 Lisp_Object Qgutter_size;
49 do { \ 50
50 switch (pos) \ 51 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
51 { \ 52 do { \
52 case TOP_GUTTER: \ 53 switch (pos) \
53 (frame)->top_gutter_was_visible = flag; \ 54 { \
54 break; \ 55 case TOP_GUTTER: \
55 case BOTTOM_GUTTER: \ 56 (frame)->top_gutter_was_visible = flag; \
56 (frame)->bottom_gutter_was_visible = flag; \ 57 break; \
57 break; \ 58 case BOTTOM_GUTTER: \
58 case LEFT_GUTTER: \ 59 (frame)->bottom_gutter_was_visible = flag; \
59 (frame)->left_gutter_was_visible = flag; \ 60 break; \
60 break; \ 61 case LEFT_GUTTER: \
61 case RIGHT_GUTTER: \ 62 (frame)->left_gutter_was_visible = flag; \
62 (frame)->right_gutter_was_visible = flag; \ 63 break; \
63 break; \ 64 case RIGHT_GUTTER: \
64 default: \ 65 (frame)->right_gutter_was_visible = flag; \
65 abort (); \ 66 break; \
66 } \ 67 default: \
68 abort (); \
69 } \
67 } while (0) 70 } while (0)
68 71
69 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos) 72 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
70 { 73 {
71 switch (pos) 74 switch (pos)
72 { 75 {
73 case TOP_GUTTER: 76 case TOP_GUTTER:
74 return (frame)->top_gutter_was_visible; 77 return frame->top_gutter_was_visible;
75 case BOTTOM_GUTTER: 78 case BOTTOM_GUTTER:
76 return (frame)->bottom_gutter_was_visible; 79 return frame->bottom_gutter_was_visible;
77 case LEFT_GUTTER: 80 case LEFT_GUTTER:
78 return (frame)->left_gutter_was_visible; 81 return frame->left_gutter_was_visible;
79 case RIGHT_GUTTER: 82 case RIGHT_GUTTER:
80 return (frame)->right_gutter_was_visible; 83 return frame->right_gutter_was_visible;
81 default: 84 default:
82 abort (); 85 abort ();
83 } 86 }
84 } 87 }
85 88
157 need to use *two* windows, the currently selected window will give 160 need to use *two* windows, the currently selected window will give
158 us the actual height, width and contents of the gutter, but if we 161 us the actual height, width and contents of the gutter, but if we
159 use this for calculating the gutter positions we run into trouble 162 use this for calculating the gutter positions we run into trouble
160 if it is not the window nearest the gutter. Instead we predetermine 163 if it is not the window nearest the gutter. Instead we predetermine
161 the nearest window and then use that.*/ 164 the nearest window and then use that.*/
162 void 165 static void
163 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y, 166 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
164 int *width, int *height) 167 int *width, int *height)
165 { 168 {
166 struct window 169 struct window
167 * top = XWINDOW (frame_topmost_window (f)), 170 * top = XWINDOW (frame_topmost_window (f)),
222 int line; 225 int line;
223 int border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos); 226 int border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
224 face_index findex = get_builtin_face_cache_index (w, Vgui_element_face); 227 face_index findex = get_builtin_face_cache_index (w, Vgui_element_face);
225 display_line_dynarr* ddla, *cdla; 228 display_line_dynarr* ddla, *cdla;
226 struct display_line *dl; 229 struct display_line *dl;
230 int cdla_len;
227 231
228 if (!f->current_display_lines) 232 if (!f->current_display_lines)
229 f->current_display_lines = Dynarr_new (display_line); 233 f->current_display_lines = Dynarr_new (display_line);
230 if (!f->desired_display_lines) 234 if (!f->desired_display_lines)
231 f->desired_display_lines = Dynarr_new (display_line); 235 f->desired_display_lines = Dynarr_new (display_line);
232 236
233 ddla = f->desired_display_lines; 237 ddla = f->desired_display_lines;
234 cdla = f->current_display_lines; 238 cdla = f->current_display_lines;
239 cdla_len = Dynarr_length (cdla);
235 240
236 XSETFRAME (frame, f); 241 XSETFRAME (frame, f);
237 242
238 get_gutter_coords (f, pos, &x, &y, &width, &height); 243 get_gutter_coords (f, pos, &x, &y, &width, &height);
239 /* clear out what we want to cover */
240 /* generate some display lines */ 244 /* generate some display lines */
241 generate_displayable_area (w, WINDOW_GUTTER (w, pos), 245 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
242 x + border_width, y + border_width, 246 x + border_width, y + border_width,
243 width - 2 * border_width, 247 width - 2 * border_width,
244 height - 2 * border_width, ddla, 0, findex); 248 height - 2 * border_width, ddla, 0, findex);
246 for (line = 0; line < Dynarr_length (ddla); line++) 250 for (line = 0; line < Dynarr_length (ddla); line++)
247 { 251 {
248 output_display_line (w, cdla, ddla, line, -1, -1); 252 output_display_line (w, cdla, ddla, line, -1, -1);
249 } 253 }
250 254
255 /* If the number of display lines has shrunk, adjust. */
256 if (cdla_len > Dynarr_length (ddla))
257 {
258 Dynarr_length (cdla) = Dynarr_length (ddla);
259 }
260
251 /* grab coordinates of last line and blank after it. */ 261 /* grab coordinates of last line and blank after it. */
252 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); 262 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
253 ypos = dl->ypos + dl->descent - dl->clip; 263 ypos = dl->ypos + dl->descent - dl->clip;
254 redisplay_clear_region (window, findex, x + border_width , ypos, 264 redisplay_clear_region (window, findex, x + border_width , ypos,
255 width - 2 * border_width, height - (ypos - y)); 265 width - 2 * border_width, height - (ypos - y) - border_width);
256
257 /* bevel the gutter area if so desired */ 266 /* bevel the gutter area if so desired */
258 if (border_width != 0) 267 if (border_width != 0)
259 { 268 {
260 MAYBE_DEVMETH (d, bevel_area, 269 MAYBE_DEVMETH (d, bevel_area,
261 (w, findex, x, y, width, height, border_width)); 270 (w, findex, x, y, width, height, border_width,
271 EDGE_ALL, EDGE_BEVEL_OUT));
262 } 272 }
263 } 273 }
264 274
265 /* sizing gutters is a pain so we try and help the user by detemining 275 /* sizing gutters is a pain so we try and help the user by detemining
266 what height will accomodate all lines. This is useless on left and 276 what height will accommodate all lines. This is useless on left and
267 right gutters as we always have a maximal number of lines. */ 277 right gutters as we always have a maximal number of lines. */
268 static Lisp_Object 278 static Lisp_Object
269 calculate_gutter_size (struct window *w, enum gutter_pos pos) 279 calculate_gutter_size (struct window *w, enum gutter_pos pos)
270 { 280 {
271 struct frame* f = XFRAME (WINDOW_FRAME (w)); 281 struct frame* f = XFRAME (WINDOW_FRAME (w));
277 is no reasonable metric to use */ 287 is no reasonable metric to use */
278 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER); 288 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
279 /* degenerate case */ 289 /* degenerate case */
280 if (NILP (WINDOW_GUTTER (w, pos)) 290 if (NILP (WINDOW_GUTTER (w, pos))
281 || 291 ||
282 !FRAME_VISIBLE_P (f)) 292 !FRAME_VISIBLE_P (f)
293 ||
294 NILP (w->buffer))
283 return Qnil; 295 return Qnil;
284 296
285 ddla = Dynarr_new (display_line); 297 ddla = Dynarr_new (display_line);
286 /* generate some display lines */ 298 /* generate some display lines */
287 generate_displayable_area (w, WINDOW_GUTTER (w, pos), 299 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
294 /* grab coordinates of last line */ 306 /* grab coordinates of last line */
295 if (Dynarr_length (ddla)) 307 if (Dynarr_length (ddla))
296 { 308 {
297 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); 309 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
298 ypos = dl->ypos + dl->descent - dl->clip; 310 ypos = dl->ypos + dl->descent - dl->clip;
299 Dynarr_free (ddla); 311 free_display_lines (ddla);
300 return make_int (ypos); 312 return make_int (ypos);
301 } 313 }
302 else 314 else
303 { 315 {
304 Dynarr_free (ddla); 316 free_display_lines (ddla);
305 return Qnil; 317 return Qnil;
306 } 318 }
307 } 319 }
308 320
309 static void 321 static void
321 } 333 }
322 334
323 void 335 void
324 update_frame_gutters (struct frame *f) 336 update_frame_gutters (struct frame *f)
325 { 337 {
326 if (f->gutter_changed || f->frame_changed || f->clear) 338 if (f->gutter_changed || f->clear ||
327 { 339 f->glyphs_changed || f->subwindows_changed ||
328 int pos; 340 f->windows_changed || f->windows_structure_changed ||
341 f->extents_changed || f->faces_changed)
342 {
343 enum gutter_pos pos;
344
345 /* We don't actually care about these when outputting the gutter
346 so locally disable them. */
347 int local_clip_changed = f->clip_changed;
348 int local_buffers_changed = f->buffers_changed;
349 f->clip_changed = 0;
350 f->buffers_changed = 0;
351
329 /* and output */ 352 /* and output */
330 353 GUTTER_POS_LOOP (pos)
331 for (pos = 0; pos < 4; pos++)
332 { 354 {
333 if (FRAME_GUTTER_VISIBLE (f, pos)) 355 if (FRAME_GUTTER_VISIBLE (f, pos))
334 output_gutter (f, pos); 356 output_gutter (f, pos);
335 else if (gutter_was_visible (f, pos)) 357 else if (gutter_was_visible (f, pos))
336 clear_gutter (f, pos); 358 clear_gutter (f, pos);
337 } 359 }
338 360 f->clip_changed = local_clip_changed;
339 } 361 f->buffers_changed = local_buffers_changed;
340 f->gutter_changed = 0; 362 f->gutter_changed = 0;
363 }
364 }
365
366 void
367 reset_gutter_display_lines (struct frame* f)
368 {
369 if (f->current_display_lines)
370 Dynarr_reset (f->current_display_lines);
341 } 371 }
342 372
343 static void 373 static void
344 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y, 374 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
345 int width, int height) 375 int width, int height)
346 { 376 {
347 int g_x, g_y, g_width, g_height; 377 int g_x, g_y, g_width, g_height;
348 int newx, newy;
349 378
350 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height); 379 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
351 380
352 if (((y + height) < g_y) || (y > (g_y + g_height))) 381 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
353 return; 382 return;
354 if (((x + width) < g_x) || (x > (g_x + g_width))) 383 if (((x + width) < g_x) || (x > (g_x + g_width)))
355 return; 384 return;
356 385
357 /* #### optimize this - redrawing the whole gutter for every expose 386 /* #### optimize this - redrawing the whole gutter for every expose
358 is very expensive. We reset the current display lines because if 387 is very expensive. We reset the current display lines because if
359 they're being exposed they are no longer current. */ 388 they're being exposed they are no longer current. */
360 if (f->current_display_lines) 389 reset_gutter_display_lines (f);
361 Dynarr_reset (f->current_display_lines);
362 /* we have to do this in-case there were subwindows where we are
363 redrawing, unfortunately sometimes this also generates expose
364 events resulting in an endless cycle of redsplay. */
365 newx = max (x, g_x);
366 newy = max (y, g_y);
367 width = min (x + width - newx, g_x + g_width - newx);
368 height = min (y + height - newy, g_y + g_height - newy);
369 redisplay_unmap_subwindows_maybe (f, newx, newy, width, height);
370 390
371 /* Even if none of the gutter is in the area, the blank region at 391 /* Even if none of the gutter is in the area, the blank region at
372 the very least must be because the first thing we did is verify 392 the very least must be because the first thing we did is verify
373 that some portion of the gutter is in the exposed region. */ 393 that some portion of the gutter is in the exposed region. */
374 output_gutter (f, pos); 394 output_gutter (f, pos);
376 396
377 void 397 void
378 redraw_exposed_gutters (struct frame *f, int x, int y, int width, 398 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
379 int height) 399 int height)
380 { 400 {
381 int pos; 401 enum gutter_pos pos;
382 for (pos = 0; pos < 4; pos++) 402 GUTTER_POS_LOOP (pos)
383 { 403 {
384 if (FRAME_GUTTER_VISIBLE (f, pos)) 404 if (FRAME_GUTTER_VISIBLE (f, pos))
385 redraw_exposed_gutter (f, pos, x, y, width, height); 405 redraw_exposed_gutter (f, pos, x, y, width, height);
386 } 406 }
387 } 407 }
388 408
389 void 409 void
390 free_frame_gutters (struct frame *f) 410 free_frame_gutters (struct frame *f)
391 { 411 {
392 if (f->current_display_lines) 412 if (f->current_display_lines)
393 Dynarr_free (f->current_display_lines); 413 {
414 free_display_lines (f->current_display_lines);
415 f->current_display_lines = 0;
416 }
394 if (f->desired_display_lines) 417 if (f->desired_display_lines)
395 Dynarr_free (f->desired_display_lines); 418 {
419 free_display_lines (f->desired_display_lines);
420 f->desired_display_lines = 0;
421 }
396 } 422 }
397 423
398 static enum gutter_pos 424 static enum gutter_pos
399 decode_gutter_position (Lisp_Object position) 425 decode_gutter_position (Lisp_Object position)
400 { 426 {
546 572
547 static void 573 static void
548 gutter_specs_changed (Lisp_Object specifier, struct window *w, 574 gutter_specs_changed (Lisp_Object specifier, struct window *w,
549 Lisp_Object oldval) 575 Lisp_Object oldval)
550 { 576 {
551 int pos; 577 enum gutter_pos pos;
552 for (pos = 0; pos< 4; pos++) 578 GUTTER_POS_LOOP (pos)
553 { 579 {
554 w->real_gutter_size[pos] = w->gutter_size[pos]; 580 w->real_gutter_size[pos] = w->gutter_size[pos];
555 if (EQ (w->real_gutter_size[pos], Qautodetect) 581 if (EQ (w->real_gutter_size[pos], Qautodetect)
556 && !NILP (w->gutter_visible_p[pos])) 582 && !NILP (w->gutter_visible_p[pos]))
557 { 583 {
571 597
572 static void 598 static void
573 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w, 599 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
574 Lisp_Object oldval) 600 Lisp_Object oldval)
575 { 601 {
576 int pos; 602 enum gutter_pos pos;
577 for (pos = 0; pos< 4; pos++) 603 GUTTER_POS_LOOP (pos)
578 { 604 {
579 w->real_gutter_size[pos] = w->gutter_size[pos]; 605 w->real_gutter_size[pos] = w->gutter_size[pos];
580 if (EQ (w->real_gutter_size[pos], Qautodetect) 606 if (EQ (w->real_gutter_size[pos], Qautodetect)
581 && !NILP (w->gutter_visible_p[pos])) 607 && !NILP (w->gutter_visible_p[pos]))
582 { 608 {
609 Lisp_Object oldval) 635 Lisp_Object oldval)
610 { 636 {
611 recompute_overlaying_specifier (Vgutter_visible_p); 637 recompute_overlaying_specifier (Vgutter_visible_p);
612 } 638 }
613 639
640
641 DECLARE_SPECIFIER_TYPE (gutter_size);
642 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
643 DEFINE_SPECIFIER_TYPE (gutter_size);
644
645 static void
646 gutter_size_validate (Lisp_Object instantiator)
647 {
648 if (NILP (instantiator))
649 return;
650
651 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
652 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
653 }
654
655 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
656 Return non-nil if OBJECT is a gutter-size specifier.
657 */
658 (object))
659 {
660 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
661 }
662
663 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
664 Ensure that all gutters are correctly showing their gutter specifier.
665 */
666 ())
667 {
668 Lisp_Object devcons, concons;
669
670 DEVICE_LOOP_NO_BREAK (devcons, concons)
671 {
672 struct device *d = XDEVICE (XCAR (devcons));
673 Lisp_Object frmcons;
674
675 DEVICE_FRAME_LOOP (frmcons, d)
676 {
677 struct frame *f = XFRAME (XCAR (frmcons));
678
679 if (FRAME_REPAINT_P (f))
680 {
681 update_frame_gutters (f);
682 }
683 }
684
685 /* We now call the output_end routine for tty frames. We delay
686 doing so in order to avoid cursor flicker. So much for 100%
687 encapsulation. */
688 if (DEVICE_TTY_P (d))
689 DEVMETH (d, output_end, (d));
690 }
691
692 return Qnil;
693 }
694
614 void 695 void
615 init_frame_gutters (struct frame *f) 696 init_frame_gutters (struct frame *f)
616 { 697 {
617 int pos; 698 enum gutter_pos pos;
618 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); 699 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
619 /* We are here as far in frame creation so cached specifiers are 700 /* We are here as far in frame creation so cached specifiers are
620 already recomputed, and possibly modified by resource 701 already recomputed, and possibly modified by resource
621 initialization. We need to recalculate autodetected gutters. */ 702 initialization. We need to recalculate autodetected gutters. */
622 for (pos = 0; pos< 4; pos++) 703 GUTTER_POS_LOOP (pos)
623 { 704 {
624 w->real_gutter_size[pos] = w->gutter_size[pos]; 705 w->real_gutter_size[pos] = w->gutter_size[pos];
625 if (EQ (w->gutter_size[pos], Qautodetect) 706 if (EQ (w->gutter_size[pos], Qautodetect)
626 && !NILP (w->gutter_visible_p[pos])) 707 && !NILP (w->gutter_visible_p[pos]))
627 { 708 {
634 715
635 void 716 void
636 syms_of_gutter (void) 717 syms_of_gutter (void)
637 { 718 {
638 DEFSUBR (Fgutter_specifier_p); 719 DEFSUBR (Fgutter_specifier_p);
720 DEFSUBR (Fgutter_size_specifier_p);
639 DEFSUBR (Fset_default_gutter_position); 721 DEFSUBR (Fset_default_gutter_position);
640 DEFSUBR (Fdefault_gutter_position); 722 DEFSUBR (Fdefault_gutter_position);
641 DEFSUBR (Fgutter_pixel_height); 723 DEFSUBR (Fgutter_pixel_height);
642 DEFSUBR (Fgutter_pixel_width); 724 DEFSUBR (Fgutter_pixel_width);
725 DEFSUBR (Fredisplay_gutter_area);
726
727 defsymbol (&Qgutter_size, "gutter-size");
643 } 728 }
644 729
645 void 730 void
646 vars_of_gutter (void) 731 vars_of_gutter (void)
647 { 732 {
656 { 741 {
657 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p"); 742 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
658 743
659 SPECIFIER_HAS_METHOD (gutter, validate); 744 SPECIFIER_HAS_METHOD (gutter, validate);
660 SPECIFIER_HAS_METHOD (gutter, after_change); 745 SPECIFIER_HAS_METHOD (gutter, after_change);
746
747 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
748
749 SPECIFIER_HAS_METHOD (gutter_size, validate);
750 }
751
752 void
753 reinit_specifier_type_create_gutter (void)
754 {
755 REINITIALIZE_SPECIFIER_TYPE (gutter);
756 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
661 } 757 }
662 758
663 void 759 void
664 specifier_vars_of_gutter (void) 760 specifier_vars_of_gutter (void)
665 { 761 {
813 909
814 If you set the height to 'autodetect the size of the gutter will be 910 If you set the height to 'autodetect the size of the gutter will be
815 calculated to be large enough to hold the contents of the gutter. This 911 calculated to be large enough to hold the contents of the gutter. This
816 is the default. 912 is the default.
817 */ ); 913 */ );
818 Vdefault_gutter_height = Fmake_specifier (Qgeneric); 914 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
819 set_specifier_caching (Vdefault_gutter_height, 915 set_specifier_caching (Vdefault_gutter_height,
820 slot_offset (struct window, 916 slot_offset (struct window,
821 default_gutter_height), 917 default_gutter_height),
822 default_gutter_size_changed_in_window, 918 default_gutter_size_changed_in_window,
823 0, 0); 919 0, 0);
840 *Height of the top gutter. 936 *Height of the top gutter.
841 This is a specifier; use `set-specifier' to change it. 937 This is a specifier; use `set-specifier' to change it.
842 938
843 See `default-gutter-height' for more information. 939 See `default-gutter-height' for more information.
844 */ ); 940 */ );
845 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgeneric); 941 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
846 set_specifier_caching (Vgutter_size[TOP_GUTTER], 942 set_specifier_caching (Vgutter_size[TOP_GUTTER],
847 slot_offset (struct window, 943 slot_offset (struct window,
848 gutter_size[TOP_GUTTER]), 944 gutter_size[TOP_GUTTER]),
849 gutter_geometry_changed_in_window, 945 gutter_geometry_changed_in_window,
850 0, 0); 946 0, 0);
854 *Height of the bottom gutter. 950 *Height of the bottom gutter.
855 This is a specifier; use `set-specifier' to change it. 951 This is a specifier; use `set-specifier' to change it.
856 952
857 See `default-gutter-height' for more information. 953 See `default-gutter-height' for more information.
858 */ ); 954 */ );
859 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgeneric); 955 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
860 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER], 956 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
861 slot_offset (struct window, 957 slot_offset (struct window,
862 gutter_size[BOTTOM_GUTTER]), 958 gutter_size[BOTTOM_GUTTER]),
863 gutter_geometry_changed_in_window, 959 gutter_geometry_changed_in_window,
864 0, 0); 960 0, 0);