1 /* Gutter implementation.
2 Copyright (C) 1999 Andy Piper.
4 This file is part of XEmacs.
6 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with XEmacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* Synched up with: Not in FSF. */
23 /* Specifers ripped-off from toolbar.c */
33 #include "redisplay.h"
37 Lisp_Object Vgutter[4];
38 Lisp_Object Vgutter_size[4];
39 Lisp_Object Vgutter_visible_p[4];
40 Lisp_Object Vgutter_border_width[4];
42 Lisp_Object Vdefault_gutter, Vdefault_gutter_visible_p;
43 Lisp_Object Vdefault_gutter_width, Vdefault_gutter_height;
44 Lisp_Object Vdefault_gutter_border_width;
46 Lisp_Object Vdefault_gutter_position;
48 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
53 (frame)->top_gutter_was_visible = flag; \
56 (frame)->bottom_gutter_was_visible = flag; \
59 (frame)->left_gutter_was_visible = flag; \
62 (frame)->right_gutter_was_visible = flag; \
69 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
74 return (frame)->top_gutter_was_visible;
76 return (frame)->bottom_gutter_was_visible;
78 return (frame)->left_gutter_was_visible;
80 return (frame)->right_gutter_was_visible;
87 frame_topmost_window (struct frame *f)
89 Lisp_Object w = FRAME_ROOT_WINDOW (f);
92 while (!NILP (XWINDOW (w)->vchild))
94 w = XWINDOW (w)->vchild;
96 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
102 frame_bottommost_window (struct frame *f)
104 Lisp_Object w = FRAME_ROOT_WINDOW (f);
107 while (!NILP (XWINDOW (w)->vchild))
109 w = XWINDOW (w)->vchild;
110 while (!NILP (XWINDOW (w)->next))
112 w = XWINDOW (w)->next;
115 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
122 frame_leftmost_window (struct frame *f)
124 Lisp_Object w = FRAME_ROOT_WINDOW (f);
127 while (!NILP (XWINDOW (w)->hchild))
129 w = XWINDOW (w)->hchild;
131 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
137 frame_rightmost_window (struct frame *f)
139 Lisp_Object w = FRAME_ROOT_WINDOW (f);
142 while (!NILP (XWINDOW (w)->hchild))
144 w = XWINDOW (w)->hchild;
145 while (!NILP (XWINDOW (w)->next))
147 w = XWINDOW (w)->next;
150 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
155 /* calculate the coordinates of a gutter for the current frame and
156 selected window. we have to be careful in calculating this as we
157 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
159 use this for calculating the gutter positions we run into trouble
160 if it is not the window nearest the gutter. Instead we predetermine
161 the nearest window and then use that.*/
163 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
164 int *width, int *height)
167 * top = XWINDOW (frame_topmost_window (f)),
168 * bot = XWINDOW (frame_bottommost_window (f));
169 /* The top and bottom gutters take precedence over the left and
174 *x = FRAME_LEFT_BORDER_END (f);
175 *y = FRAME_TOP_BORDER_END (f);
176 *width = FRAME_RIGHT_BORDER_START (f)
177 - FRAME_LEFT_BORDER_END (f);
178 *height = FRAME_TOP_GUTTER_BOUNDS (f);
182 *x = FRAME_LEFT_BORDER_END (f);
183 *y = WINDOW_BOTTOM (bot)
184 - FRAME_BOTTOM_GUTTER_BOUNDS (f);
185 *width = FRAME_RIGHT_BORDER_START (f)
186 - FRAME_LEFT_BORDER_END (f);
187 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f);
191 *x = FRAME_LEFT_BORDER_END (f);
192 *y = WINDOW_TEXT_TOP (top);
193 *width = FRAME_LEFT_GUTTER_BOUNDS (f);
194 *height = WINDOW_BOTTOM (bot)
195 - (WINDOW_TEXT_TOP (top)
196 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
200 *x = FRAME_RIGHT_BORDER_START (f)
201 - FRAME_RIGHT_GUTTER_BOUNDS (f);
202 *y = WINDOW_TEXT_TOP (top);
203 *width = FRAME_RIGHT_GUTTER_BOUNDS (f);
204 *height = WINDOW_BOTTOM (bot)
205 - (WINDOW_TEXT_TOP (top)
206 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
215 output_gutter (struct frame *f, enum gutter_pos pos)
218 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
219 struct device *d = XDEVICE (f->device);
220 struct window* w = XWINDOW (window);
221 int x, y, width, height, ypos;
223 int border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
224 face_index findex = get_builtin_face_cache_index (w, Vgui_element_face);
225 display_line_dynarr* ddla, *cdla;
226 struct display_line *dl;
228 if (!f->current_display_lines)
229 f->current_display_lines = Dynarr_new (display_line);
230 if (!f->desired_display_lines)
231 f->desired_display_lines = Dynarr_new (display_line);
233 ddla = f->desired_display_lines;
234 cdla = f->current_display_lines;
236 XSETFRAME (frame, f);
238 get_gutter_coords (f, pos, &x, &y, &width, &height);
239 /* clear out what we want to cover */
240 /* generate some display lines */
241 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
242 x + border_width, y + border_width,
243 width - 2 * border_width,
244 height - 2 * border_width, ddla, 0, findex);
245 /* Output each line. */
246 for (line = 0; line < Dynarr_length (ddla); line++)
248 output_display_line (w, cdla, ddla, line, -1, -1);
251 /* grab coordinates of last line and blank after it. */
252 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
253 ypos = dl->ypos + dl->descent - dl->clip;
254 redisplay_clear_region (window, findex, x + border_width , ypos,
255 width - 2 * border_width, height - (ypos - y));
257 /* bevel the gutter area if so desired */
258 if (border_width != 0)
260 MAYBE_DEVMETH (d, bevel_area,
261 (w, findex, x, y, width, height, border_width));
265 /* 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
267 right gutters as we always have a maximal number of lines. */
269 calculate_gutter_size (struct window *w, enum gutter_pos pos)
271 struct frame* f = XFRAME (WINDOW_FRAME (w));
273 display_line_dynarr* ddla;
274 struct display_line *dl;
276 /* we cannot autodetect gutter sizes for the left and right as there
277 is no reasonable metric to use */
278 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
279 /* degenerate case */
280 if (NILP (WINDOW_GUTTER (w, pos))
282 !FRAME_VISIBLE_P (f))
285 ddla = Dynarr_new (display_line);
286 /* generate some display lines */
287 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
288 FRAME_LEFT_BORDER_END (f),
290 FRAME_RIGHT_BORDER_START (f)
291 - FRAME_LEFT_BORDER_END (f),
294 /* grab coordinates of last line */
295 if (Dynarr_length (ddla))
297 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
298 ypos = dl->ypos + dl->descent - dl->clip;
300 return make_int (ypos);
310 clear_gutter (struct frame *f, enum gutter_pos pos)
312 int x, y, width, height;
313 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
314 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
316 get_gutter_coords (f, pos, &x, &y, &width, &height);
318 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
320 redisplay_clear_region (window, findex, x, y, width, height);
324 update_frame_gutters (struct frame *f)
326 if (f->gutter_changed || f->frame_changed || f->clear)
331 for (pos = 0; pos < 4; pos++)
333 if (FRAME_GUTTER_VISIBLE (f, pos))
334 output_gutter (f, pos);
335 else if (gutter_was_visible (f, pos))
336 clear_gutter (f, pos);
340 f->gutter_changed = 0;
344 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
345 int width, int height)
347 int g_x, g_y, g_width, g_height;
350 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
352 if (((y + height) < g_y) || (y > (g_y + g_height)))
354 if (((x + width) < g_x) || (x > (g_x + g_width)))
357 /* #### optimize this - redrawing the whole gutter for every expose
358 is very expensive. We reset the current display lines because if
359 they're being exposed they are no longer current. */
360 if (f->current_display_lines)
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. */
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);
371 /* 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
373 that some portion of the gutter is in the exposed region. */
374 output_gutter (f, pos);
378 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
382 for (pos = 0; pos < 4; pos++)
384 if (FRAME_GUTTER_VISIBLE (f, pos))
385 redraw_exposed_gutter (f, pos, x, y, width, height);
390 free_frame_gutters (struct frame *f)
392 if (f->current_display_lines)
393 Dynarr_free (f->current_display_lines);
394 if (f->desired_display_lines)
395 Dynarr_free (f->desired_display_lines);
398 static enum gutter_pos
399 decode_gutter_position (Lisp_Object position)
401 if (EQ (position, Qtop)) return TOP_GUTTER;
402 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
403 if (EQ (position, Qleft)) return LEFT_GUTTER;
404 if (EQ (position, Qright)) return RIGHT_GUTTER;
405 signal_simple_error ("Invalid gutter position", position);
407 return TOP_GUTTER; /* not reached */
410 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
411 Set the position that the `default-gutter' will be displayed at.
412 Valid positions are 'top, 'bottom, 'left and 'right.
413 See `default-gutter-position'.
417 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
418 enum gutter_pos new = decode_gutter_position (position);
422 /* The following calls will automatically cause the dirty
423 flags to be set; we delay frame size changes to avoid
424 lots of frame flickering. */
425 /* #### I think this should be GC protected. -sb */
426 hold_frame_size_changes ();
427 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
428 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
429 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
430 set_specifier_fallback (Vgutter_size[new],
431 new == TOP_GUTTER || new == BOTTOM_GUTTER
432 ? Vdefault_gutter_height
433 : Vdefault_gutter_width);
434 set_specifier_fallback (Vgutter_border_width[cur],
435 list1 (Fcons (Qnil, Qzero)));
436 set_specifier_fallback (Vgutter_border_width[new],
437 Vdefault_gutter_border_width);
438 set_specifier_fallback (Vgutter_visible_p[cur],
439 list1 (Fcons (Qnil, Qt)));
440 set_specifier_fallback (Vgutter_visible_p[new],
441 Vdefault_gutter_visible_p);
442 Vdefault_gutter_position = position;
443 unhold_frame_size_changes ();
449 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
450 Return the position that the `default-gutter' will be displayed at.
451 The `default-gutter' will only be displayed here if the corresponding
452 position-specific gutter specifier does not provide a value.
456 return Vdefault_gutter_position;
459 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
460 Return the pixel width of the gutter at POS in LOCALE.
461 POS defaults to the default gutter position. LOCALE defaults to
466 int x, y, width, height;
467 enum gutter_pos p = TOP_GUTTER;
468 struct frame *f = decode_frame (FW_FRAME (locale));
471 pos = Vdefault_gutter_position;
472 p = decode_gutter_position (pos);
474 get_gutter_coords (f, p, &x, &y, &width, &height);
475 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
477 return make_int (width);
480 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
481 Return the pixel height of the gutter at POS in LOCALE.
482 POS defaults to the default gutter position. LOCALE defaults to
487 int x, y, width, height;
488 enum gutter_pos p = TOP_GUTTER;
489 struct frame *f = decode_frame (FW_FRAME (locale));
492 pos = Vdefault_gutter_position;
493 p = decode_gutter_position (pos);
495 get_gutter_coords (f, p, &x, &y, &width, &height);
496 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
498 return make_int (height);
501 DEFINE_SPECIFIER_TYPE (gutter);
504 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
510 gutter_validate (Lisp_Object instantiator)
512 if (NILP (instantiator))
515 if (!STRINGP (instantiator))
516 signal_simple_error ("Gutter spec must be string or nil", instantiator);
519 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
520 Return non-nil if OBJECT is a gutter specifier.
521 Gutter specifiers are used to specify the format of a gutter.
522 The values of the variables `default-gutter', `top-gutter',
523 `left-gutter', `right-gutter', and `bottom-gutter' are always
526 Valid gutter instantiators are called "gutter descriptors"
527 and are lists of vectors. See `default-gutter' for a description
532 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
537 Helper for invalidating the real specifier when default
538 specifier caching changes
541 recompute_overlaying_specifier (Lisp_Object real_one[4])
543 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
544 Fset_specifier_dirty_flag (real_one[pos]);
548 gutter_specs_changed (Lisp_Object specifier, struct window *w,
552 for (pos = 0; pos< 4; pos++)
554 w->real_gutter_size[pos] = w->gutter_size[pos];
555 if (EQ (w->real_gutter_size[pos], Qautodetect)
556 && !NILP (w->gutter_visible_p[pos]))
558 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
562 MARK_WINDOWS_CHANGED (w);
566 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
569 recompute_overlaying_specifier (Vgutter);
573 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
577 for (pos = 0; pos< 4; pos++)
579 w->real_gutter_size[pos] = w->gutter_size[pos];
580 if (EQ (w->real_gutter_size[pos], Qautodetect)
581 && !NILP (w->gutter_visible_p[pos]))
583 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
588 MARK_WINDOWS_CHANGED (w);
592 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
595 recompute_overlaying_specifier (Vgutter_size);
599 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
603 recompute_overlaying_specifier (Vgutter_border_width);
607 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
611 recompute_overlaying_specifier (Vgutter_visible_p);
615 init_frame_gutters (struct frame *f)
618 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
619 /* We are here as far in frame creation so cached specifiers are
620 already recomputed, and possibly modified by resource
621 initialization. We need to recalculate autodetected gutters. */
622 for (pos = 0; pos< 4; pos++)
624 w->real_gutter_size[pos] = w->gutter_size[pos];
625 if (EQ (w->gutter_size[pos], Qautodetect)
626 && !NILP (w->gutter_visible_p[pos]))
628 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
630 MARK_WINDOWS_CHANGED (w);
636 syms_of_gutter (void)
638 DEFSUBR (Fgutter_specifier_p);
639 DEFSUBR (Fset_default_gutter_position);
640 DEFSUBR (Fdefault_gutter_position);
641 DEFSUBR (Fgutter_pixel_height);
642 DEFSUBR (Fgutter_pixel_width);
646 vars_of_gutter (void)
648 staticpro (&Vdefault_gutter_position);
649 Vdefault_gutter_position = Qtop;
655 specifier_type_create_gutter (void)
657 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
659 SPECIFIER_HAS_METHOD (gutter, validate);
660 SPECIFIER_HAS_METHOD (gutter, after_change);
664 specifier_vars_of_gutter (void)
668 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
669 Specifier for a fallback gutter.
670 Use `set-specifier' to change this.
672 The position of this gutter is specified in the function
673 `default-gutter-position'. If the corresponding position-specific
674 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
675 does not specify a gutter in a particular domain (usually a window),
676 then the value of `default-gutter' in that domain, if any, will be
679 Note that the gutter at any particular position will not be
680 displayed unless its visibility flag is true and its thickness
681 \(width or height, depending on orientation) is non-zero. The
682 visibility is controlled by the specifiers `top-gutter-visible-p',
683 `bottom-gutter-visible-p', `left-gutter-visible-p', and
684 `right-gutter-visible-p', and the thickness is controlled by the
685 specifiers `top-gutter-height', `bottom-gutter-height',
686 `left-gutter-width', and `right-gutter-width'.
688 Note that one of the four visibility specifiers inherits from
689 `default-gutter-visibility' and one of the four thickness
690 specifiers inherits from either `default-gutter-width' or
691 `default-gutter-height' (depending on orientation), just
692 like for the gutter description specifiers (e.g. `top-gutter')
695 Therefore, if you are setting `default-gutter', you should control
696 the visibility and thickness using `default-gutter-visible-p',
697 `default-gutter-width', and `default-gutter-height', rather than
698 using position-specific specifiers. That way, you will get sane
699 behavior if the user changes the default gutter position.
701 The gutter value should be a string or nil. You can attach extents and
702 glyphs to the string and hence display glyphs and text in other fonts
707 Vdefault_gutter = Fmake_specifier (Qgutter);
708 /* #### It would be even nicer if the specifier caching
709 automatically knew about specifier fallbacks, so we didn't
710 have to do it ourselves. */
711 set_specifier_caching (Vdefault_gutter,
712 slot_offset (struct window,
714 default_gutter_specs_changed,
717 DEFVAR_SPECIFIER ("top-gutter",
718 &Vgutter[TOP_GUTTER] /*
719 Specifier for the gutter at the top of the frame.
720 Use `set-specifier' to change this.
721 See `default-gutter' for a description of a valid gutter instantiator.
723 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
724 set_specifier_caching (Vgutter[TOP_GUTTER],
725 slot_offset (struct window,
727 gutter_specs_changed,
730 DEFVAR_SPECIFIER ("bottom-gutter",
731 &Vgutter[BOTTOM_GUTTER] /*
732 Specifier for the gutter at the bottom of the frame.
733 Use `set-specifier' to change this.
734 See `default-gutter' for a description of a valid gutter instantiator.
736 Note that, unless the `default-gutter-position' is `bottom', by
737 default the height of the bottom gutter (controlled by
738 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
739 displayed even if you provide a value for `bottom-gutter'.
741 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
742 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
743 slot_offset (struct window,
744 gutter[BOTTOM_GUTTER]),
745 gutter_specs_changed,
748 DEFVAR_SPECIFIER ("left-gutter",
749 &Vgutter[LEFT_GUTTER] /*
750 Specifier for the gutter at the left edge of the frame.
751 Use `set-specifier' to change this.
752 See `default-gutter' for a description of a valid gutter instantiator.
754 Note that, unless the `default-gutter-position' is `left', by
755 default the height of the left gutter (controlled by
756 `left-gutter-width') is 0; thus, a left gutter will not be
757 displayed even if you provide a value for `left-gutter'.
759 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
760 set_specifier_caching (Vgutter[LEFT_GUTTER],
761 slot_offset (struct window,
762 gutter[LEFT_GUTTER]),
763 gutter_specs_changed,
766 DEFVAR_SPECIFIER ("right-gutter",
767 &Vgutter[RIGHT_GUTTER] /*
768 Specifier for the gutter at the right edge of the frame.
769 Use `set-specifier' to change this.
770 See `default-gutter' for a description of a valid gutter instantiator.
772 Note that, unless the `default-gutter-position' is `right', by
773 default the height of the right gutter (controlled by
774 `right-gutter-width') is 0; thus, a right gutter will not be
775 displayed even if you provide a value for `right-gutter'.
777 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
778 set_specifier_caching (Vgutter[RIGHT_GUTTER],
779 slot_offset (struct window,
780 gutter[RIGHT_GUTTER]),
781 gutter_specs_changed,
784 /* initially, top inherits from default; this can be
785 changed with `set-default-gutter-position'. */
786 fb = list1 (Fcons (Qnil, Qnil));
787 set_specifier_fallback (Vdefault_gutter, fb);
788 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
789 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
790 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
791 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
793 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
794 *Height of the default gutter, if it's oriented horizontally.
795 This is a specifier; use `set-specifier' to change it.
797 The position of the default gutter is specified by the function
798 `set-default-gutter-position'. If the corresponding position-specific
799 gutter thickness specifier (e.g. `top-gutter-height' if
800 `default-gutter-position' is 'top) does not specify a thickness in a
801 particular domain (a window or a frame), then the value of
802 `default-gutter-height' or `default-gutter-width' (depending on the
803 gutter orientation) in that domain, if any, will be used instead.
805 Note that `default-gutter-height' is only used when
806 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
807 is only used when `default-gutter-position' is 'left or 'right.
809 Note that all of the position-specific gutter thickness specifiers
810 have a fallback value of zero when they do not correspond to the
811 default gutter. Therefore, you will have to set a non-zero thickness
812 value if you want a position-specific gutter to be displayed.
814 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
818 Vdefault_gutter_height = Fmake_specifier (Qgeneric);
819 set_specifier_caching (Vdefault_gutter_height,
820 slot_offset (struct window,
821 default_gutter_height),
822 default_gutter_size_changed_in_window,
825 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
826 *Width of the default gutter, if it's oriented vertically.
827 This is a specifier; use `set-specifier' to change it.
829 See `default-gutter-height' for more information.
831 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
832 set_specifier_caching (Vdefault_gutter_width,
833 slot_offset (struct window,
834 default_gutter_width),
835 default_gutter_size_changed_in_window,
838 DEFVAR_SPECIFIER ("top-gutter-height",
839 &Vgutter_size[TOP_GUTTER] /*
840 *Height of the top gutter.
841 This is a specifier; use `set-specifier' to change it.
843 See `default-gutter-height' for more information.
845 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgeneric);
846 set_specifier_caching (Vgutter_size[TOP_GUTTER],
847 slot_offset (struct window,
848 gutter_size[TOP_GUTTER]),
849 gutter_geometry_changed_in_window,
852 DEFVAR_SPECIFIER ("bottom-gutter-height",
853 &Vgutter_size[BOTTOM_GUTTER] /*
854 *Height of the bottom gutter.
855 This is a specifier; use `set-specifier' to change it.
857 See `default-gutter-height' for more information.
859 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgeneric);
860 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
861 slot_offset (struct window,
862 gutter_size[BOTTOM_GUTTER]),
863 gutter_geometry_changed_in_window,
866 DEFVAR_SPECIFIER ("left-gutter-width",
867 &Vgutter_size[LEFT_GUTTER] /*
868 *Width of left gutter.
869 This is a specifier; use `set-specifier' to change it.
871 See `default-gutter-height' for more information.
873 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
874 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
875 slot_offset (struct window,
876 gutter_size[LEFT_GUTTER]),
877 gutter_geometry_changed_in_window,
880 DEFVAR_SPECIFIER ("right-gutter-width",
881 &Vgutter_size[RIGHT_GUTTER] /*
882 *Width of right gutter.
883 This is a specifier; use `set-specifier' to change it.
885 See `default-gutter-height' for more information.
887 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
888 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
889 slot_offset (struct window,
890 gutter_size[RIGHT_GUTTER]),
891 gutter_geometry_changed_in_window,
896 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
898 #ifdef HAVE_X_WINDOWS
899 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
901 #ifdef HAVE_MS_WINDOWS
902 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
905 set_specifier_fallback (Vdefault_gutter_height, fb);
909 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
911 #ifdef HAVE_X_WINDOWS
912 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
914 #ifdef HAVE_MS_WINDOWS
915 fb = Fcons (Fcons (list1 (Qmswindows),
916 make_int (DEFAULT_GUTTER_WIDTH)), fb);
919 set_specifier_fallback (Vdefault_gutter_width, fb);
921 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
922 fb = list1 (Fcons (Qnil, Qzero));
923 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
924 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
925 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
927 DEFVAR_SPECIFIER ("default-gutter-border-width",
928 &Vdefault_gutter_border_width /*
929 *Width of the border around the default gutter.
930 This is a specifier; use `set-specifier' to change it.
932 The position of the default gutter is specified by the function
933 `set-default-gutter-position'. If the corresponding position-specific
934 gutter border width specifier (e.g. `top-gutter-border-width' if
935 `default-gutter-position' is 'top) does not specify a border width in a
936 particular domain (a window or a frame), then the value of
937 `default-gutter-border-width' in that domain, if any, will be used
941 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
942 set_specifier_caching (Vdefault_gutter_border_width,
943 slot_offset (struct window,
944 default_gutter_border_width),
945 default_gutter_border_width_changed_in_window,
948 DEFVAR_SPECIFIER ("top-gutter-border-width",
949 &Vgutter_border_width[TOP_GUTTER] /*
950 *Border width of the top gutter.
951 This is a specifier; use `set-specifier' to change it.
953 See `default-gutter-height' for more information.
955 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
956 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
957 slot_offset (struct window,
958 gutter_border_width[TOP_GUTTER]),
959 gutter_geometry_changed_in_window,
962 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
963 &Vgutter_border_width[BOTTOM_GUTTER] /*
964 *Border width of the bottom gutter.
965 This is a specifier; use `set-specifier' to change it.
967 See `default-gutter-height' for more information.
969 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
970 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
971 slot_offset (struct window,
972 gutter_border_width[BOTTOM_GUTTER]),
973 gutter_geometry_changed_in_window,
976 DEFVAR_SPECIFIER ("left-gutter-border-width",
977 &Vgutter_border_width[LEFT_GUTTER] /*
978 *Border width of left gutter.
979 This is a specifier; use `set-specifier' to change it.
981 See `default-gutter-height' for more information.
983 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
984 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
985 slot_offset (struct window,
986 gutter_border_width[LEFT_GUTTER]),
987 gutter_geometry_changed_in_window,
990 DEFVAR_SPECIFIER ("right-gutter-border-width",
991 &Vgutter_border_width[RIGHT_GUTTER] /*
992 *Border width of right gutter.
993 This is a specifier; use `set-specifier' to change it.
995 See `default-gutter-height' for more information.
997 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
998 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
999 slot_offset (struct window,
1000 gutter_border_width[RIGHT_GUTTER]),
1001 gutter_geometry_changed_in_window,
1006 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1008 #ifdef HAVE_X_WINDOWS
1009 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1011 #ifdef HAVE_MS_WINDOWS
1012 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1015 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1017 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1018 fb = list1 (Fcons (Qnil, Qzero));
1019 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1020 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1021 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1023 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1024 *Whether the default gutter is visible.
1025 This is a specifier; use `set-specifier' to change it.
1027 The position of the default gutter is specified by the function
1028 `set-default-gutter-position'. If the corresponding position-specific
1029 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1030 `default-gutter-position' is 'top) does not specify a visible-p value
1031 in a particular domain (a window or a frame), then the value of
1032 `default-gutter-visible-p' in that domain, if any, will be used
1035 `default-gutter-visible-p' and all of the position-specific gutter
1036 visibility specifiers have a fallback value of true.
1038 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean);
1039 set_specifier_caching (Vdefault_gutter_visible_p,
1040 slot_offset (struct window,
1041 default_gutter_visible_p),
1042 default_gutter_visible_p_changed_in_window,
1045 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1046 &Vgutter_visible_p[TOP_GUTTER] /*
1047 *Whether the top gutter is visible.
1048 This is a specifier; use `set-specifier' to change it.
1050 See `default-gutter-visible-p' for more information.
1052 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean);
1053 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1054 slot_offset (struct window,
1055 gutter_visible_p[TOP_GUTTER]),
1056 gutter_geometry_changed_in_window,
1059 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1060 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1061 *Whether the bottom gutter is visible.
1062 This is a specifier; use `set-specifier' to change it.
1064 See `default-gutter-visible-p' for more information.
1066 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean);
1067 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1068 slot_offset (struct window,
1069 gutter_visible_p[BOTTOM_GUTTER]),
1070 gutter_geometry_changed_in_window,
1073 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1074 &Vgutter_visible_p[LEFT_GUTTER] /*
1075 *Whether the left gutter is visible.
1076 This is a specifier; use `set-specifier' to change it.
1078 See `default-gutter-visible-p' for more information.
1080 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean);
1081 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1082 slot_offset (struct window,
1083 gutter_visible_p[LEFT_GUTTER]),
1084 gutter_geometry_changed_in_window,
1087 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1088 &Vgutter_visible_p[RIGHT_GUTTER] /*
1089 *Whether the right gutter is visible.
1090 This is a specifier; use `set-specifier' to change it.
1092 See `default-gutter-visible-p' for more information.
1094 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean);
1095 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1096 slot_offset (struct window,
1097 gutter_visible_p[RIGHT_GUTTER]),
1098 gutter_geometry_changed_in_window,
1101 /* initially, top inherits from default; this can be
1102 changed with `set-default-gutter-position'. */
1103 fb = list1 (Fcons (Qnil, Qt));
1104 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1105 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1106 Vdefault_gutter_visible_p);
1107 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1108 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1109 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);