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 /* written by Andy Piper <andy@xemacs.org> with specifiers partially
24 ripped-off from toolbar.c */
34 #include "redisplay.h"
38 Lisp_Object Vgutter[4];
39 Lisp_Object Vgutter_size[4];
40 Lisp_Object Vgutter_visible_p[4];
41 Lisp_Object Vgutter_border_width[4];
43 Lisp_Object Vdefault_gutter, Vdefault_gutter_visible_p;
44 Lisp_Object Vdefault_gutter_width, Vdefault_gutter_height;
45 Lisp_Object Vdefault_gutter_border_width;
47 Lisp_Object Vdefault_gutter_position;
49 Lisp_Object Qgutter_size;
51 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
56 (frame)->top_gutter_was_visible = flag; \
59 (frame)->bottom_gutter_was_visible = flag; \
62 (frame)->left_gutter_was_visible = flag; \
65 (frame)->right_gutter_was_visible = flag; \
72 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
77 return frame->top_gutter_was_visible;
79 return frame->bottom_gutter_was_visible;
81 return frame->left_gutter_was_visible;
83 return frame->right_gutter_was_visible;
90 frame_topmost_window (struct frame *f)
92 Lisp_Object w = FRAME_ROOT_WINDOW (f);
95 while (!NILP (XWINDOW (w)->vchild))
97 w = XWINDOW (w)->vchild;
99 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
105 frame_bottommost_window (struct frame *f)
107 Lisp_Object w = FRAME_ROOT_WINDOW (f);
110 while (!NILP (XWINDOW (w)->vchild))
112 w = XWINDOW (w)->vchild;
113 while (!NILP (XWINDOW (w)->next))
115 w = XWINDOW (w)->next;
118 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
125 frame_leftmost_window (struct frame *f)
127 Lisp_Object w = FRAME_ROOT_WINDOW (f);
130 while (!NILP (XWINDOW (w)->hchild))
132 w = XWINDOW (w)->hchild;
134 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
140 frame_rightmost_window (struct frame *f)
142 Lisp_Object w = FRAME_ROOT_WINDOW (f);
145 while (!NILP (XWINDOW (w)->hchild))
147 w = XWINDOW (w)->hchild;
148 while (!NILP (XWINDOW (w)->next))
150 w = XWINDOW (w)->next;
153 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
158 /* calculate the coordinates of a gutter for the current frame and
159 selected window. we have to be careful in calculating this as we
160 need to use *two* windows, the currently selected window will give
161 us the actual height, width and contents of the gutter, but if we
162 use this for calculating the gutter positions we run into trouble
163 if it is not the window nearest the gutter. Instead we predetermine
164 the nearest window and then use that.*/
166 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
167 int *width, int *height)
170 * top = XWINDOW (frame_topmost_window (f)),
171 * bot = XWINDOW (frame_bottommost_window (f));
172 /* The top and bottom gutters take precedence over the left and
177 *x = FRAME_LEFT_BORDER_END (f);
178 *y = FRAME_TOP_BORDER_END (f);
179 *width = FRAME_RIGHT_BORDER_START (f)
180 - FRAME_LEFT_BORDER_END (f);
181 *height = FRAME_TOP_GUTTER_BOUNDS (f);
185 *x = FRAME_LEFT_BORDER_END (f);
186 *y = WINDOW_BOTTOM (bot)
187 - FRAME_BOTTOM_GUTTER_BOUNDS (f);
188 *width = FRAME_RIGHT_BORDER_START (f)
189 - FRAME_LEFT_BORDER_END (f);
190 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f);
194 *x = FRAME_LEFT_BORDER_END (f);
195 *y = WINDOW_TEXT_TOP (top);
196 *width = FRAME_LEFT_GUTTER_BOUNDS (f);
197 *height = WINDOW_BOTTOM (bot)
198 - (WINDOW_TEXT_TOP (top)
199 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
203 *x = FRAME_RIGHT_BORDER_START (f)
204 - FRAME_RIGHT_GUTTER_BOUNDS (f);
205 *y = WINDOW_TEXT_TOP (top);
206 *width = FRAME_RIGHT_GUTTER_BOUNDS (f);
207 *height = WINDOW_BOTTOM (bot)
208 - (WINDOW_TEXT_TOP (top)
209 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
218 output_gutter (struct frame *f, enum gutter_pos pos)
221 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
222 struct device *d = XDEVICE (f->device);
223 struct window* w = XWINDOW (window);
224 int x, y, width, height, ypos;
226 int border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
227 face_index findex = get_builtin_face_cache_index (w, Vgui_element_face);
228 display_line_dynarr* ddla, *cdla;
229 struct display_line *dl;
232 if (!f->current_display_lines)
233 f->current_display_lines = Dynarr_new (display_line);
234 if (!f->desired_display_lines)
235 f->desired_display_lines = Dynarr_new (display_line);
237 ddla = f->desired_display_lines;
238 cdla = f->current_display_lines;
239 cdla_len = Dynarr_length (cdla);
241 XSETFRAME (frame, f);
243 get_gutter_coords (f, pos, &x, &y, &width, &height);
244 /* generate some display lines */
245 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
246 x + border_width, y + border_width,
247 width - 2 * border_width,
248 height - 2 * border_width, ddla, 0, findex);
249 /* Output each line. */
250 for (line = 0; line < Dynarr_length (ddla); line++)
252 output_display_line (w, cdla, ddla, line, -1, -1);
255 /* If the number of display lines has shrunk, adjust. */
256 if (cdla_len > Dynarr_length (ddla))
258 Dynarr_length (cdla) = Dynarr_length (ddla);
261 /* grab coordinates of last line and blank after it. */
262 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
263 ypos = dl->ypos + dl->descent - dl->clip;
264 redisplay_clear_region (window, findex, x + border_width , ypos,
265 width - 2 * border_width, height - (ypos - y) - border_width);
266 /* bevel the gutter area if so desired */
267 if (border_width != 0)
269 MAYBE_DEVMETH (d, bevel_area,
270 (w, findex, x, y, width, height, border_width,
271 EDGE_ALL, EDGE_BEVEL_OUT));
275 /* sizing gutters is a pain so we try and help the user by detemining
276 what height will accommodate all lines. This is useless on left and
277 right gutters as we always have a maximal number of lines. */
279 calculate_gutter_size (struct window *w, enum gutter_pos pos)
281 struct frame* f = XFRAME (WINDOW_FRAME (w));
283 display_line_dynarr* ddla;
284 struct display_line *dl;
286 /* we cannot autodetect gutter sizes for the left and right as there
287 is no reasonable metric to use */
288 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
289 /* degenerate case */
290 if (NILP (WINDOW_GUTTER (w, pos))
297 ddla = Dynarr_new (display_line);
298 /* generate some display lines */
299 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
300 FRAME_LEFT_BORDER_END (f),
302 FRAME_RIGHT_BORDER_START (f)
303 - FRAME_LEFT_BORDER_END (f),
306 /* grab coordinates of last line */
307 if (Dynarr_length (ddla))
309 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
310 ypos = dl->ypos + dl->descent - dl->clip;
311 free_display_lines (ddla);
312 return make_int (ypos);
316 free_display_lines (ddla);
322 clear_gutter (struct frame *f, enum gutter_pos pos)
324 int x, y, width, height;
325 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
326 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
328 get_gutter_coords (f, pos, &x, &y, &width, &height);
330 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
332 redisplay_clear_region (window, findex, x, y, width, height);
336 update_frame_gutters (struct frame *f)
338 if (f->gutter_changed || f->clear ||
339 f->glyphs_changed || f->subwindows_changed ||
340 f->windows_changed || f->windows_structure_changed ||
341 f->extents_changed || f->faces_changed)
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;
350 f->buffers_changed = 0;
353 GUTTER_POS_LOOP (pos)
355 if (FRAME_GUTTER_VISIBLE (f, pos))
356 output_gutter (f, pos);
357 else if (gutter_was_visible (f, pos))
358 clear_gutter (f, pos);
360 f->clip_changed = local_clip_changed;
361 f->buffers_changed = local_buffers_changed;
362 f->gutter_changed = 0;
367 reset_gutter_display_lines (struct frame* f)
369 if (f->current_display_lines)
370 Dynarr_reset (f->current_display_lines);
374 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
375 int width, int height)
377 int g_x, g_y, g_width, g_height;
379 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
381 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
383 if (((x + width) < g_x) || (x > (g_x + g_width)))
386 /* #### optimize this - redrawing the whole gutter for every expose
387 is very expensive. We reset the current display lines because if
388 they're being exposed they are no longer current. */
389 reset_gutter_display_lines (f);
391 /* Even if none of the gutter is in the area, the blank region at
392 the very least must be because the first thing we did is verify
393 that some portion of the gutter is in the exposed region. */
394 output_gutter (f, pos);
398 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
402 GUTTER_POS_LOOP (pos)
404 if (FRAME_GUTTER_VISIBLE (f, pos))
405 redraw_exposed_gutter (f, pos, x, y, width, height);
410 free_frame_gutters (struct frame *f)
412 if (f->current_display_lines)
414 free_display_lines (f->current_display_lines);
415 f->current_display_lines = 0;
417 if (f->desired_display_lines)
419 free_display_lines (f->desired_display_lines);
420 f->desired_display_lines = 0;
424 static enum gutter_pos
425 decode_gutter_position (Lisp_Object position)
427 if (EQ (position, Qtop)) return TOP_GUTTER;
428 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
429 if (EQ (position, Qleft)) return LEFT_GUTTER;
430 if (EQ (position, Qright)) return RIGHT_GUTTER;
431 signal_simple_error ("Invalid gutter position", position);
433 return TOP_GUTTER; /* not reached */
436 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
437 Set the position that the `default-gutter' will be displayed at.
438 Valid positions are 'top, 'bottom, 'left and 'right.
439 See `default-gutter-position'.
443 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
444 enum gutter_pos new = decode_gutter_position (position);
448 /* The following calls will automatically cause the dirty
449 flags to be set; we delay frame size changes to avoid
450 lots of frame flickering. */
451 /* #### I think this should be GC protected. -sb */
452 hold_frame_size_changes ();
453 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
454 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
455 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
456 set_specifier_fallback (Vgutter_size[new],
457 new == TOP_GUTTER || new == BOTTOM_GUTTER
458 ? Vdefault_gutter_height
459 : Vdefault_gutter_width);
460 set_specifier_fallback (Vgutter_border_width[cur],
461 list1 (Fcons (Qnil, Qzero)));
462 set_specifier_fallback (Vgutter_border_width[new],
463 Vdefault_gutter_border_width);
464 set_specifier_fallback (Vgutter_visible_p[cur],
465 list1 (Fcons (Qnil, Qt)));
466 set_specifier_fallback (Vgutter_visible_p[new],
467 Vdefault_gutter_visible_p);
468 Vdefault_gutter_position = position;
469 unhold_frame_size_changes ();
475 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
476 Return the position that the `default-gutter' will be displayed at.
477 The `default-gutter' will only be displayed here if the corresponding
478 position-specific gutter specifier does not provide a value.
482 return Vdefault_gutter_position;
485 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
486 Return the pixel width of the gutter at POS in LOCALE.
487 POS defaults to the default gutter position. LOCALE defaults to
492 int x, y, width, height;
493 enum gutter_pos p = TOP_GUTTER;
494 struct frame *f = decode_frame (FW_FRAME (locale));
497 pos = Vdefault_gutter_position;
498 p = decode_gutter_position (pos);
500 get_gutter_coords (f, p, &x, &y, &width, &height);
501 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
503 return make_int (width);
506 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
507 Return the pixel height of the gutter at POS in LOCALE.
508 POS defaults to the default gutter position. LOCALE defaults to
513 int x, y, width, height;
514 enum gutter_pos p = TOP_GUTTER;
515 struct frame *f = decode_frame (FW_FRAME (locale));
518 pos = Vdefault_gutter_position;
519 p = decode_gutter_position (pos);
521 get_gutter_coords (f, p, &x, &y, &width, &height);
522 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
524 return make_int (height);
527 DEFINE_SPECIFIER_TYPE (gutter);
530 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
536 gutter_validate (Lisp_Object instantiator)
538 if (NILP (instantiator))
541 if (!STRINGP (instantiator))
542 signal_simple_error ("Gutter spec must be string or nil", instantiator);
545 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
546 Return non-nil if OBJECT is a gutter specifier.
547 Gutter specifiers are used to specify the format of a gutter.
548 The values of the variables `default-gutter', `top-gutter',
549 `left-gutter', `right-gutter', and `bottom-gutter' are always
552 Valid gutter instantiators are called "gutter descriptors"
553 and are lists of vectors. See `default-gutter' for a description
558 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
563 Helper for invalidating the real specifier when default
564 specifier caching changes
567 recompute_overlaying_specifier (Lisp_Object real_one[4])
569 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
570 Fset_specifier_dirty_flag (real_one[pos]);
574 gutter_specs_changed (Lisp_Object specifier, struct window *w,
578 GUTTER_POS_LOOP (pos)
580 w->real_gutter_size[pos] = w->gutter_size[pos];
581 if (EQ (w->real_gutter_size[pos], Qautodetect)
582 && !NILP (w->gutter_visible_p[pos]))
584 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
588 MARK_WINDOWS_CHANGED (w);
592 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
595 recompute_overlaying_specifier (Vgutter);
599 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
603 GUTTER_POS_LOOP (pos)
605 w->real_gutter_size[pos] = w->gutter_size[pos];
606 if (EQ (w->real_gutter_size[pos], Qautodetect)
607 && !NILP (w->gutter_visible_p[pos]))
609 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
614 MARK_WINDOWS_CHANGED (w);
618 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
621 recompute_overlaying_specifier (Vgutter_size);
625 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
629 recompute_overlaying_specifier (Vgutter_border_width);
633 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
637 recompute_overlaying_specifier (Vgutter_visible_p);
641 DECLARE_SPECIFIER_TYPE (gutter_size);
642 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
643 DEFINE_SPECIFIER_TYPE (gutter_size);
646 gutter_size_validate (Lisp_Object instantiator)
648 if (NILP (instantiator))
651 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
652 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
655 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
656 Return non-nil if OBJECT is a gutter-size specifier.
660 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
663 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
664 Ensure that all gutters are correctly showing their gutter specifier.
668 Lisp_Object devcons, concons;
670 DEVICE_LOOP_NO_BREAK (devcons, concons)
672 struct device *d = XDEVICE (XCAR (devcons));
675 DEVICE_FRAME_LOOP (frmcons, d)
677 struct frame *f = XFRAME (XCAR (frmcons));
679 if (FRAME_REPAINT_P (f))
681 update_frame_gutters (f);
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%
688 if (DEVICE_TTY_P (d))
689 DEVMETH (d, output_end, (d));
696 init_frame_gutters (struct frame *f)
699 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
700 /* We are here as far in frame creation so cached specifiers are
701 already recomputed, and possibly modified by resource
702 initialization. We need to recalculate autodetected gutters. */
703 GUTTER_POS_LOOP (pos)
705 w->real_gutter_size[pos] = w->gutter_size[pos];
706 if (EQ (w->gutter_size[pos], Qautodetect)
707 && !NILP (w->gutter_visible_p[pos]))
709 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
711 MARK_WINDOWS_CHANGED (w);
717 syms_of_gutter (void)
719 DEFSUBR (Fgutter_specifier_p);
720 DEFSUBR (Fgutter_size_specifier_p);
721 DEFSUBR (Fset_default_gutter_position);
722 DEFSUBR (Fdefault_gutter_position);
723 DEFSUBR (Fgutter_pixel_height);
724 DEFSUBR (Fgutter_pixel_width);
725 DEFSUBR (Fredisplay_gutter_area);
727 defsymbol (&Qgutter_size, "gutter-size");
731 vars_of_gutter (void)
733 staticpro (&Vdefault_gutter_position);
734 Vdefault_gutter_position = Qtop;
740 specifier_type_create_gutter (void)
742 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
744 SPECIFIER_HAS_METHOD (gutter, validate);
745 SPECIFIER_HAS_METHOD (gutter, after_change);
747 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
749 SPECIFIER_HAS_METHOD (gutter_size, validate);
753 reinit_specifier_type_create_gutter (void)
755 REINITIALIZE_SPECIFIER_TYPE (gutter);
756 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
760 specifier_vars_of_gutter (void)
764 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
765 Specifier for a fallback gutter.
766 Use `set-specifier' to change this.
768 The position of this gutter is specified in the function
769 `default-gutter-position'. If the corresponding position-specific
770 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
771 does not specify a gutter in a particular domain (usually a window),
772 then the value of `default-gutter' in that domain, if any, will be
775 Note that the gutter at any particular position will not be
776 displayed unless its visibility flag is true and its thickness
777 \(width or height, depending on orientation) is non-zero. The
778 visibility is controlled by the specifiers `top-gutter-visible-p',
779 `bottom-gutter-visible-p', `left-gutter-visible-p', and
780 `right-gutter-visible-p', and the thickness is controlled by the
781 specifiers `top-gutter-height', `bottom-gutter-height',
782 `left-gutter-width', and `right-gutter-width'.
784 Note that one of the four visibility specifiers inherits from
785 `default-gutter-visibility' and one of the four thickness
786 specifiers inherits from either `default-gutter-width' or
787 `default-gutter-height' (depending on orientation), just
788 like for the gutter description specifiers (e.g. `top-gutter')
791 Therefore, if you are setting `default-gutter', you should control
792 the visibility and thickness using `default-gutter-visible-p',
793 `default-gutter-width', and `default-gutter-height', rather than
794 using position-specific specifiers. That way, you will get sane
795 behavior if the user changes the default gutter position.
797 The gutter value should be a string or nil. You can attach extents and
798 glyphs to the string and hence display glyphs and text in other fonts
803 Vdefault_gutter = Fmake_specifier (Qgutter);
804 /* #### It would be even nicer if the specifier caching
805 automatically knew about specifier fallbacks, so we didn't
806 have to do it ourselves. */
807 set_specifier_caching (Vdefault_gutter,
808 offsetof (struct window, default_gutter),
809 default_gutter_specs_changed,
812 DEFVAR_SPECIFIER ("top-gutter",
813 &Vgutter[TOP_GUTTER] /*
814 Specifier for the gutter at the top of the frame.
815 Use `set-specifier' to change this.
816 See `default-gutter' for a description of a valid gutter instantiator.
818 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
819 set_specifier_caching (Vgutter[TOP_GUTTER],
820 offsetof (struct window, gutter[TOP_GUTTER]),
821 gutter_specs_changed,
824 DEFVAR_SPECIFIER ("bottom-gutter",
825 &Vgutter[BOTTOM_GUTTER] /*
826 Specifier for the gutter at the bottom of the frame.
827 Use `set-specifier' to change this.
828 See `default-gutter' for a description of a valid gutter instantiator.
830 Note that, unless the `default-gutter-position' is `bottom', by
831 default the height of the bottom gutter (controlled by
832 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
833 displayed even if you provide a value for `bottom-gutter'.
835 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
836 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
837 offsetof (struct window, gutter[BOTTOM_GUTTER]),
838 gutter_specs_changed,
841 DEFVAR_SPECIFIER ("left-gutter",
842 &Vgutter[LEFT_GUTTER] /*
843 Specifier for the gutter at the left edge of the frame.
844 Use `set-specifier' to change this.
845 See `default-gutter' for a description of a valid gutter instantiator.
847 Note that, unless the `default-gutter-position' is `left', by
848 default the height of the left gutter (controlled by
849 `left-gutter-width') is 0; thus, a left gutter will not be
850 displayed even if you provide a value for `left-gutter'.
852 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
853 set_specifier_caching (Vgutter[LEFT_GUTTER],
854 offsetof (struct window, gutter[LEFT_GUTTER]),
855 gutter_specs_changed,
858 DEFVAR_SPECIFIER ("right-gutter",
859 &Vgutter[RIGHT_GUTTER] /*
860 Specifier for the gutter at the right edge of the frame.
861 Use `set-specifier' to change this.
862 See `default-gutter' for a description of a valid gutter instantiator.
864 Note that, unless the `default-gutter-position' is `right', by
865 default the height of the right gutter (controlled by
866 `right-gutter-width') is 0; thus, a right gutter will not be
867 displayed even if you provide a value for `right-gutter'.
869 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
870 set_specifier_caching (Vgutter[RIGHT_GUTTER],
871 offsetof (struct window, gutter[RIGHT_GUTTER]),
872 gutter_specs_changed,
875 /* initially, top inherits from default; this can be
876 changed with `set-default-gutter-position'. */
877 fb = list1 (Fcons (Qnil, Qnil));
878 set_specifier_fallback (Vdefault_gutter, fb);
879 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
880 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
881 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
882 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
884 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
885 *Height of the default gutter, if it's oriented horizontally.
886 This is a specifier; use `set-specifier' to change it.
888 The position of the default gutter is specified by the function
889 `set-default-gutter-position'. If the corresponding position-specific
890 gutter thickness specifier (e.g. `top-gutter-height' if
891 `default-gutter-position' is 'top) does not specify a thickness in a
892 particular domain (a window or a frame), then the value of
893 `default-gutter-height' or `default-gutter-width' (depending on the
894 gutter orientation) in that domain, if any, will be used instead.
896 Note that `default-gutter-height' is only used when
897 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
898 is only used when `default-gutter-position' is 'left or 'right.
900 Note that all of the position-specific gutter thickness specifiers
901 have a fallback value of zero when they do not correspond to the
902 default gutter. Therefore, you will have to set a non-zero thickness
903 value if you want a position-specific gutter to be displayed.
905 If you set the height to 'autodetect the size of the gutter will be
906 calculated to be large enough to hold the contents of the gutter. This
909 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
910 set_specifier_caching (Vdefault_gutter_height,
911 offsetof (struct window, default_gutter_height),
912 default_gutter_size_changed_in_window,
915 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
916 *Width of the default gutter, if it's oriented vertically.
917 This is a specifier; use `set-specifier' to change it.
919 See `default-gutter-height' for more information.
921 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
922 set_specifier_caching (Vdefault_gutter_width,
923 offsetof (struct window, default_gutter_width),
924 default_gutter_size_changed_in_window,
927 DEFVAR_SPECIFIER ("top-gutter-height",
928 &Vgutter_size[TOP_GUTTER] /*
929 *Height of the top gutter.
930 This is a specifier; use `set-specifier' to change it.
932 See `default-gutter-height' for more information.
934 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
935 set_specifier_caching (Vgutter_size[TOP_GUTTER],
936 offsetof (struct window, gutter_size[TOP_GUTTER]),
937 gutter_geometry_changed_in_window,
940 DEFVAR_SPECIFIER ("bottom-gutter-height",
941 &Vgutter_size[BOTTOM_GUTTER] /*
942 *Height of the bottom gutter.
943 This is a specifier; use `set-specifier' to change it.
945 See `default-gutter-height' for more information.
947 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
948 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
949 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
950 gutter_geometry_changed_in_window,
953 DEFVAR_SPECIFIER ("left-gutter-width",
954 &Vgutter_size[LEFT_GUTTER] /*
955 *Width of left gutter.
956 This is a specifier; use `set-specifier' to change it.
958 See `default-gutter-height' for more information.
960 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
961 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
962 offsetof (struct window, gutter_size[LEFT_GUTTER]),
963 gutter_geometry_changed_in_window,
966 DEFVAR_SPECIFIER ("right-gutter-width",
967 &Vgutter_size[RIGHT_GUTTER] /*
968 *Width of right gutter.
969 This is a specifier; use `set-specifier' to change it.
971 See `default-gutter-height' for more information.
973 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
974 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
975 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
976 gutter_geometry_changed_in_window,
981 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
983 #ifdef HAVE_X_WINDOWS
984 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
986 #ifdef HAVE_MS_WINDOWS
987 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
990 set_specifier_fallback (Vdefault_gutter_height, fb);
994 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
996 #ifdef HAVE_X_WINDOWS
997 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
999 #ifdef HAVE_MS_WINDOWS
1000 fb = Fcons (Fcons (list1 (Qmswindows),
1001 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1004 set_specifier_fallback (Vdefault_gutter_width, fb);
1006 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1007 fb = list1 (Fcons (Qnil, Qzero));
1008 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1009 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1010 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1012 DEFVAR_SPECIFIER ("default-gutter-border-width",
1013 &Vdefault_gutter_border_width /*
1014 *Width of the border around the default gutter.
1015 This is a specifier; use `set-specifier' to change it.
1017 The position of the default gutter is specified by the function
1018 `set-default-gutter-position'. If the corresponding position-specific
1019 gutter border width specifier (e.g. `top-gutter-border-width' if
1020 `default-gutter-position' is 'top) does not specify a border width in a
1021 particular domain (a window or a frame), then the value of
1022 `default-gutter-border-width' in that domain, if any, will be used
1026 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1027 set_specifier_caching (Vdefault_gutter_border_width,
1028 offsetof (struct window, default_gutter_border_width),
1029 default_gutter_border_width_changed_in_window,
1032 DEFVAR_SPECIFIER ("top-gutter-border-width",
1033 &Vgutter_border_width[TOP_GUTTER] /*
1034 *Border width of the top gutter.
1035 This is a specifier; use `set-specifier' to change it.
1037 See `default-gutter-height' for more information.
1039 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1040 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1041 offsetof (struct window,
1042 gutter_border_width[TOP_GUTTER]),
1043 gutter_geometry_changed_in_window,
1046 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1047 &Vgutter_border_width[BOTTOM_GUTTER] /*
1048 *Border width of the bottom gutter.
1049 This is a specifier; use `set-specifier' to change it.
1051 See `default-gutter-height' for more information.
1053 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1054 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1055 offsetof (struct window,
1056 gutter_border_width[BOTTOM_GUTTER]),
1057 gutter_geometry_changed_in_window,
1060 DEFVAR_SPECIFIER ("left-gutter-border-width",
1061 &Vgutter_border_width[LEFT_GUTTER] /*
1062 *Border width of left gutter.
1063 This is a specifier; use `set-specifier' to change it.
1065 See `default-gutter-height' for more information.
1067 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1068 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1069 offsetof (struct window,
1070 gutter_border_width[LEFT_GUTTER]),
1071 gutter_geometry_changed_in_window,
1074 DEFVAR_SPECIFIER ("right-gutter-border-width",
1075 &Vgutter_border_width[RIGHT_GUTTER] /*
1076 *Border width of right gutter.
1077 This is a specifier; use `set-specifier' to change it.
1079 See `default-gutter-height' for more information.
1081 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1082 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1083 offsetof (struct window,
1084 gutter_border_width[RIGHT_GUTTER]),
1085 gutter_geometry_changed_in_window,
1090 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1092 #ifdef HAVE_X_WINDOWS
1093 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1095 #ifdef HAVE_MS_WINDOWS
1096 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1099 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1101 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1102 fb = list1 (Fcons (Qnil, Qzero));
1103 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1104 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1105 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1107 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1108 *Whether the default gutter is visible.
1109 This is a specifier; use `set-specifier' to change it.
1111 The position of the default gutter is specified by the function
1112 `set-default-gutter-position'. If the corresponding position-specific
1113 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1114 `default-gutter-position' is 'top) does not specify a visible-p value
1115 in a particular domain (a window or a frame), then the value of
1116 `default-gutter-visible-p' in that domain, if any, will be used
1119 `default-gutter-visible-p' and all of the position-specific gutter
1120 visibility specifiers have a fallback value of true.
1122 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean);
1123 set_specifier_caching (Vdefault_gutter_visible_p,
1124 offsetof (struct window,
1125 default_gutter_visible_p),
1126 default_gutter_visible_p_changed_in_window,
1129 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1130 &Vgutter_visible_p[TOP_GUTTER] /*
1131 *Whether the top gutter is visible.
1132 This is a specifier; use `set-specifier' to change it.
1134 See `default-gutter-visible-p' for more information.
1136 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean);
1137 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1138 offsetof (struct window,
1139 gutter_visible_p[TOP_GUTTER]),
1140 gutter_geometry_changed_in_window,
1143 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1144 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1145 *Whether the bottom gutter is visible.
1146 This is a specifier; use `set-specifier' to change it.
1148 See `default-gutter-visible-p' for more information.
1150 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean);
1151 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1152 offsetof (struct window,
1153 gutter_visible_p[BOTTOM_GUTTER]),
1154 gutter_geometry_changed_in_window,
1157 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1158 &Vgutter_visible_p[LEFT_GUTTER] /*
1159 *Whether the left gutter is visible.
1160 This is a specifier; use `set-specifier' to change it.
1162 See `default-gutter-visible-p' for more information.
1164 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean);
1165 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1166 offsetof (struct window,
1167 gutter_visible_p[LEFT_GUTTER]),
1168 gutter_geometry_changed_in_window,
1171 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1172 &Vgutter_visible_p[RIGHT_GUTTER] /*
1173 *Whether the right gutter is visible.
1174 This is a specifier; use `set-specifier' to change it.
1176 See `default-gutter-visible-p' for more information.
1178 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean);
1179 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1180 offsetof (struct window,
1181 gutter_visible_p[RIGHT_GUTTER]),
1182 gutter_geometry_changed_in_window,
1185 /* initially, top inherits from default; this can be
1186 changed with `set-default-gutter-position'. */
1187 fb = list1 (Fcons (Qnil, Qt));
1188 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1189 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1190 Vdefault_gutter_visible_p);
1191 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1192 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1193 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);