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 slot_offset (struct window,
810 default_gutter_specs_changed,
813 DEFVAR_SPECIFIER ("top-gutter",
814 &Vgutter[TOP_GUTTER] /*
815 Specifier for the gutter at the top of the frame.
816 Use `set-specifier' to change this.
817 See `default-gutter' for a description of a valid gutter instantiator.
819 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
820 set_specifier_caching (Vgutter[TOP_GUTTER],
821 slot_offset (struct window,
823 gutter_specs_changed,
826 DEFVAR_SPECIFIER ("bottom-gutter",
827 &Vgutter[BOTTOM_GUTTER] /*
828 Specifier for the gutter at the bottom of the frame.
829 Use `set-specifier' to change this.
830 See `default-gutter' for a description of a valid gutter instantiator.
832 Note that, unless the `default-gutter-position' is `bottom', by
833 default the height of the bottom gutter (controlled by
834 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
835 displayed even if you provide a value for `bottom-gutter'.
837 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
838 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
839 slot_offset (struct window,
840 gutter[BOTTOM_GUTTER]),
841 gutter_specs_changed,
844 DEFVAR_SPECIFIER ("left-gutter",
845 &Vgutter[LEFT_GUTTER] /*
846 Specifier for the gutter at the left edge of the frame.
847 Use `set-specifier' to change this.
848 See `default-gutter' for a description of a valid gutter instantiator.
850 Note that, unless the `default-gutter-position' is `left', by
851 default the height of the left gutter (controlled by
852 `left-gutter-width') is 0; thus, a left gutter will not be
853 displayed even if you provide a value for `left-gutter'.
855 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
856 set_specifier_caching (Vgutter[LEFT_GUTTER],
857 slot_offset (struct window,
858 gutter[LEFT_GUTTER]),
859 gutter_specs_changed,
862 DEFVAR_SPECIFIER ("right-gutter",
863 &Vgutter[RIGHT_GUTTER] /*
864 Specifier for the gutter at the right edge of the frame.
865 Use `set-specifier' to change this.
866 See `default-gutter' for a description of a valid gutter instantiator.
868 Note that, unless the `default-gutter-position' is `right', by
869 default the height of the right gutter (controlled by
870 `right-gutter-width') is 0; thus, a right gutter will not be
871 displayed even if you provide a value for `right-gutter'.
873 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
874 set_specifier_caching (Vgutter[RIGHT_GUTTER],
875 slot_offset (struct window,
876 gutter[RIGHT_GUTTER]),
877 gutter_specs_changed,
880 /* initially, top inherits from default; this can be
881 changed with `set-default-gutter-position'. */
882 fb = list1 (Fcons (Qnil, Qnil));
883 set_specifier_fallback (Vdefault_gutter, fb);
884 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
885 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
886 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
887 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
889 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
890 *Height of the default gutter, if it's oriented horizontally.
891 This is a specifier; use `set-specifier' to change it.
893 The position of the default gutter is specified by the function
894 `set-default-gutter-position'. If the corresponding position-specific
895 gutter thickness specifier (e.g. `top-gutter-height' if
896 `default-gutter-position' is 'top) does not specify a thickness in a
897 particular domain (a window or a frame), then the value of
898 `default-gutter-height' or `default-gutter-width' (depending on the
899 gutter orientation) in that domain, if any, will be used instead.
901 Note that `default-gutter-height' is only used when
902 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
903 is only used when `default-gutter-position' is 'left or 'right.
905 Note that all of the position-specific gutter thickness specifiers
906 have a fallback value of zero when they do not correspond to the
907 default gutter. Therefore, you will have to set a non-zero thickness
908 value if you want a position-specific gutter to be displayed.
910 If you set the height to 'autodetect the size of the gutter will be
911 calculated to be large enough to hold the contents of the gutter. This
914 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
915 set_specifier_caching (Vdefault_gutter_height,
916 slot_offset (struct window,
917 default_gutter_height),
918 default_gutter_size_changed_in_window,
921 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
922 *Width of the default gutter, if it's oriented vertically.
923 This is a specifier; use `set-specifier' to change it.
925 See `default-gutter-height' for more information.
927 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
928 set_specifier_caching (Vdefault_gutter_width,
929 slot_offset (struct window,
930 default_gutter_width),
931 default_gutter_size_changed_in_window,
934 DEFVAR_SPECIFIER ("top-gutter-height",
935 &Vgutter_size[TOP_GUTTER] /*
936 *Height of the top gutter.
937 This is a specifier; use `set-specifier' to change it.
939 See `default-gutter-height' for more information.
941 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
942 set_specifier_caching (Vgutter_size[TOP_GUTTER],
943 slot_offset (struct window,
944 gutter_size[TOP_GUTTER]),
945 gutter_geometry_changed_in_window,
948 DEFVAR_SPECIFIER ("bottom-gutter-height",
949 &Vgutter_size[BOTTOM_GUTTER] /*
950 *Height of the bottom gutter.
951 This is a specifier; use `set-specifier' to change it.
953 See `default-gutter-height' for more information.
955 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
956 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
957 slot_offset (struct window,
958 gutter_size[BOTTOM_GUTTER]),
959 gutter_geometry_changed_in_window,
962 DEFVAR_SPECIFIER ("left-gutter-width",
963 &Vgutter_size[LEFT_GUTTER] /*
964 *Width of left gutter.
965 This is a specifier; use `set-specifier' to change it.
967 See `default-gutter-height' for more information.
969 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
970 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
971 slot_offset (struct window,
972 gutter_size[LEFT_GUTTER]),
973 gutter_geometry_changed_in_window,
976 DEFVAR_SPECIFIER ("right-gutter-width",
977 &Vgutter_size[RIGHT_GUTTER] /*
978 *Width of right gutter.
979 This is a specifier; use `set-specifier' to change it.
981 See `default-gutter-height' for more information.
983 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
984 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
985 slot_offset (struct window,
986 gutter_size[RIGHT_GUTTER]),
987 gutter_geometry_changed_in_window,
992 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
994 #ifdef HAVE_X_WINDOWS
995 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
997 #ifdef HAVE_MS_WINDOWS
998 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1001 set_specifier_fallback (Vdefault_gutter_height, fb);
1005 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1007 #ifdef HAVE_X_WINDOWS
1008 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
1010 #ifdef HAVE_MS_WINDOWS
1011 fb = Fcons (Fcons (list1 (Qmswindows),
1012 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1015 set_specifier_fallback (Vdefault_gutter_width, fb);
1017 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1018 fb = list1 (Fcons (Qnil, Qzero));
1019 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1020 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1021 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1023 DEFVAR_SPECIFIER ("default-gutter-border-width",
1024 &Vdefault_gutter_border_width /*
1025 *Width of the border around the default gutter.
1026 This is a specifier; use `set-specifier' to change it.
1028 The position of the default gutter is specified by the function
1029 `set-default-gutter-position'. If the corresponding position-specific
1030 gutter border width specifier (e.g. `top-gutter-border-width' if
1031 `default-gutter-position' is 'top) does not specify a border width in a
1032 particular domain (a window or a frame), then the value of
1033 `default-gutter-border-width' in that domain, if any, will be used
1037 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1038 set_specifier_caching (Vdefault_gutter_border_width,
1039 slot_offset (struct window,
1040 default_gutter_border_width),
1041 default_gutter_border_width_changed_in_window,
1044 DEFVAR_SPECIFIER ("top-gutter-border-width",
1045 &Vgutter_border_width[TOP_GUTTER] /*
1046 *Border width of the top gutter.
1047 This is a specifier; use `set-specifier' to change it.
1049 See `default-gutter-height' for more information.
1051 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1052 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1053 slot_offset (struct window,
1054 gutter_border_width[TOP_GUTTER]),
1055 gutter_geometry_changed_in_window,
1058 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1059 &Vgutter_border_width[BOTTOM_GUTTER] /*
1060 *Border width of the bottom gutter.
1061 This is a specifier; use `set-specifier' to change it.
1063 See `default-gutter-height' for more information.
1065 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1066 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1067 slot_offset (struct window,
1068 gutter_border_width[BOTTOM_GUTTER]),
1069 gutter_geometry_changed_in_window,
1072 DEFVAR_SPECIFIER ("left-gutter-border-width",
1073 &Vgutter_border_width[LEFT_GUTTER] /*
1074 *Border width of left gutter.
1075 This is a specifier; use `set-specifier' to change it.
1077 See `default-gutter-height' for more information.
1079 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1080 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1081 slot_offset (struct window,
1082 gutter_border_width[LEFT_GUTTER]),
1083 gutter_geometry_changed_in_window,
1086 DEFVAR_SPECIFIER ("right-gutter-border-width",
1087 &Vgutter_border_width[RIGHT_GUTTER] /*
1088 *Border width of right gutter.
1089 This is a specifier; use `set-specifier' to change it.
1091 See `default-gutter-height' for more information.
1093 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1094 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1095 slot_offset (struct window,
1096 gutter_border_width[RIGHT_GUTTER]),
1097 gutter_geometry_changed_in_window,
1102 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1104 #ifdef HAVE_X_WINDOWS
1105 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1107 #ifdef HAVE_MS_WINDOWS
1108 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1111 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1113 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1114 fb = list1 (Fcons (Qnil, Qzero));
1115 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1116 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1117 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1119 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1120 *Whether the default gutter is visible.
1121 This is a specifier; use `set-specifier' to change it.
1123 The position of the default gutter is specified by the function
1124 `set-default-gutter-position'. If the corresponding position-specific
1125 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1126 `default-gutter-position' is 'top) does not specify a visible-p value
1127 in a particular domain (a window or a frame), then the value of
1128 `default-gutter-visible-p' in that domain, if any, will be used
1131 `default-gutter-visible-p' and all of the position-specific gutter
1132 visibility specifiers have a fallback value of true.
1134 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean);
1135 set_specifier_caching (Vdefault_gutter_visible_p,
1136 slot_offset (struct window,
1137 default_gutter_visible_p),
1138 default_gutter_visible_p_changed_in_window,
1141 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1142 &Vgutter_visible_p[TOP_GUTTER] /*
1143 *Whether the top gutter is visible.
1144 This is a specifier; use `set-specifier' to change it.
1146 See `default-gutter-visible-p' for more information.
1148 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean);
1149 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1150 slot_offset (struct window,
1151 gutter_visible_p[TOP_GUTTER]),
1152 gutter_geometry_changed_in_window,
1155 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1156 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1157 *Whether the bottom gutter is visible.
1158 This is a specifier; use `set-specifier' to change it.
1160 See `default-gutter-visible-p' for more information.
1162 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean);
1163 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1164 slot_offset (struct window,
1165 gutter_visible_p[BOTTOM_GUTTER]),
1166 gutter_geometry_changed_in_window,
1169 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1170 &Vgutter_visible_p[LEFT_GUTTER] /*
1171 *Whether the left gutter is visible.
1172 This is a specifier; use `set-specifier' to change it.
1174 See `default-gutter-visible-p' for more information.
1176 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean);
1177 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1178 slot_offset (struct window,
1179 gutter_visible_p[LEFT_GUTTER]),
1180 gutter_geometry_changed_in_window,
1183 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1184 &Vgutter_visible_p[RIGHT_GUTTER] /*
1185 *Whether the right gutter is visible.
1186 This is a specifier; use `set-specifier' to change it.
1188 See `default-gutter-visible-p' for more information.
1190 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean);
1191 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1192 slot_offset (struct window,
1193 gutter_visible_p[RIGHT_GUTTER]),
1194 gutter_geometry_changed_in_window,
1197 /* initially, top inherits from default; this can be
1198 changed with `set-default-gutter-position'. */
1199 fb = list1 (Fcons (Qnil, Qt));
1200 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1201 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1202 Vdefault_gutter_visible_p);
1203 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1204 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1205 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);