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;
225 int line, border_width;
227 display_line_dynarr* ddla, *cdla;
228 struct display_line *dl;
231 if (!WINDOW_LIVE_P (w))
234 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
235 findex = get_builtin_face_cache_index (w, Vgui_element_face);
237 if (!f->current_display_lines)
238 f->current_display_lines = Dynarr_new (display_line);
239 if (!f->desired_display_lines)
240 f->desired_display_lines = Dynarr_new (display_line);
242 ddla = f->desired_display_lines;
243 cdla = f->current_display_lines;
244 cdla_len = Dynarr_length (cdla);
246 XSETFRAME (frame, f);
248 get_gutter_coords (f, pos, &x, &y, &width, &height);
249 /* generate some display lines */
250 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
251 x + border_width, y + border_width,
252 width - 2 * border_width,
253 height - 2 * border_width, ddla, 0, findex);
254 /* Output each line. */
255 for (line = 0; line < Dynarr_length (ddla); line++)
257 output_display_line (w, cdla, ddla, line, -1, -1);
260 /* If the number of display lines has shrunk, adjust. */
261 if (cdla_len > Dynarr_length (ddla))
263 Dynarr_length (cdla) = Dynarr_length (ddla);
266 /* grab coordinates of last line and blank after it. */
267 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
268 ypos = dl->ypos + dl->descent - dl->clip;
269 redisplay_clear_region (window, findex, x + border_width , ypos,
270 width - 2 * border_width, height - (ypos - y) - border_width);
271 /* bevel the gutter area if so desired */
272 if (border_width != 0)
274 MAYBE_DEVMETH (d, bevel_area,
275 (w, findex, x, y, width, height, border_width,
276 EDGE_ALL, EDGE_BEVEL_OUT));
280 /* sizing gutters is a pain so we try and help the user by detemining
281 what height will accommodate all lines. This is useless on left and
282 right gutters as we always have a maximal number of lines. */
284 calculate_gutter_size (struct window *w, enum gutter_pos pos)
286 struct frame* f = XFRAME (WINDOW_FRAME (w));
288 display_line_dynarr* ddla;
289 struct display_line *dl;
291 /* we cannot autodetect gutter sizes for the left and right as there
292 is no reasonable metric to use */
293 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
294 /* degenerate case */
295 if (NILP (WINDOW_GUTTER (w, pos))
302 ddla = Dynarr_new (display_line);
303 /* generate some display lines */
304 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
305 FRAME_LEFT_BORDER_END (f),
307 FRAME_RIGHT_BORDER_START (f)
308 - FRAME_LEFT_BORDER_END (f),
311 /* grab coordinates of last line */
312 if (Dynarr_length (ddla))
314 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
315 ypos = dl->ypos + dl->descent - dl->clip;
316 free_display_lines (ddla);
317 return make_int (ypos);
321 free_display_lines (ddla);
327 clear_gutter (struct frame *f, enum gutter_pos pos)
329 int x, y, width, height;
330 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
331 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
333 get_gutter_coords (f, pos, &x, &y, &width, &height);
335 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
337 redisplay_clear_region (window, findex, x, y, width, height);
341 update_frame_gutters (struct frame *f)
343 if (f->gutter_changed || f->clear ||
344 f->glyphs_changed || f->subwindows_changed ||
345 f->windows_changed || f->windows_structure_changed ||
346 f->extents_changed || f->faces_changed)
350 /* We don't actually care about these when outputting the gutter
351 so locally disable them. */
352 int local_clip_changed = f->clip_changed;
353 int local_buffers_changed = f->buffers_changed;
355 f->buffers_changed = 0;
358 GUTTER_POS_LOOP (pos)
360 if (FRAME_GUTTER_VISIBLE (f, pos))
361 output_gutter (f, pos);
362 else if (gutter_was_visible (f, pos))
363 clear_gutter (f, pos);
365 f->clip_changed = local_clip_changed;
366 f->buffers_changed = local_buffers_changed;
367 f->gutter_changed = 0;
372 reset_gutter_display_lines (struct frame* f)
374 if (f->current_display_lines)
375 Dynarr_reset (f->current_display_lines);
379 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
380 int width, int height)
382 int g_x, g_y, g_width, g_height;
384 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
386 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
388 if (((x + width) < g_x) || (x > (g_x + g_width)))
391 /* #### optimize this - redrawing the whole gutter for every expose
392 is very expensive. We reset the current display lines because if
393 they're being exposed they are no longer current. */
394 reset_gutter_display_lines (f);
396 /* Even if none of the gutter is in the area, the blank region at
397 the very least must be because the first thing we did is verify
398 that some portion of the gutter is in the exposed region. */
399 output_gutter (f, pos);
403 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
407 GUTTER_POS_LOOP (pos)
409 if (FRAME_GUTTER_VISIBLE (f, pos))
410 redraw_exposed_gutter (f, pos, x, y, width, height);
415 free_frame_gutters (struct frame *f)
417 if (f->current_display_lines)
419 free_display_lines (f->current_display_lines);
420 f->current_display_lines = 0;
422 if (f->desired_display_lines)
424 free_display_lines (f->desired_display_lines);
425 f->desired_display_lines = 0;
429 static enum gutter_pos
430 decode_gutter_position (Lisp_Object position)
432 if (EQ (position, Qtop)) return TOP_GUTTER;
433 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
434 if (EQ (position, Qleft)) return LEFT_GUTTER;
435 if (EQ (position, Qright)) return RIGHT_GUTTER;
436 signal_simple_error ("Invalid gutter position", position);
438 return TOP_GUTTER; /* not reached */
441 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
442 Set the position that the `default-gutter' will be displayed at.
443 Valid positions are 'top, 'bottom, 'left and 'right.
444 See `default-gutter-position'.
448 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
449 enum gutter_pos new = decode_gutter_position (position);
453 /* The following calls will automatically cause the dirty
454 flags to be set; we delay frame size changes to avoid
455 lots of frame flickering. */
456 /* #### I think this should be GC protected. -sb */
457 hold_frame_size_changes ();
458 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
459 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
460 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
461 set_specifier_fallback (Vgutter_size[new],
462 new == TOP_GUTTER || new == BOTTOM_GUTTER
463 ? Vdefault_gutter_height
464 : Vdefault_gutter_width);
465 set_specifier_fallback (Vgutter_border_width[cur],
466 list1 (Fcons (Qnil, Qzero)));
467 set_specifier_fallback (Vgutter_border_width[new],
468 Vdefault_gutter_border_width);
469 set_specifier_fallback (Vgutter_visible_p[cur],
470 list1 (Fcons (Qnil, Qt)));
471 set_specifier_fallback (Vgutter_visible_p[new],
472 Vdefault_gutter_visible_p);
473 Vdefault_gutter_position = position;
474 unhold_frame_size_changes ();
480 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
481 Return the position that the `default-gutter' will be displayed at.
482 The `default-gutter' will only be displayed here if the corresponding
483 position-specific gutter specifier does not provide a value.
487 return Vdefault_gutter_position;
490 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
491 Return the pixel width of the gutter at POS in LOCALE.
492 POS defaults to the default gutter position. LOCALE defaults to
497 int x, y, width, height;
498 enum gutter_pos p = TOP_GUTTER;
499 struct frame *f = decode_frame (FW_FRAME (locale));
502 pos = Vdefault_gutter_position;
503 p = decode_gutter_position (pos);
505 get_gutter_coords (f, p, &x, &y, &width, &height);
506 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
508 return make_int (width);
511 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
512 Return the pixel height of the gutter at POS in LOCALE.
513 POS defaults to the default gutter position. LOCALE defaults to
518 int x, y, width, height;
519 enum gutter_pos p = TOP_GUTTER;
520 struct frame *f = decode_frame (FW_FRAME (locale));
523 pos = Vdefault_gutter_position;
524 p = decode_gutter_position (pos);
526 get_gutter_coords (f, p, &x, &y, &width, &height);
527 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
529 return make_int (height);
532 DEFINE_SPECIFIER_TYPE (gutter);
535 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
541 gutter_validate (Lisp_Object instantiator)
543 if (NILP (instantiator))
546 if (!STRINGP (instantiator))
547 signal_simple_error ("Gutter spec must be string or nil", instantiator);
550 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
551 Return non-nil if OBJECT is a gutter specifier.
552 Gutter specifiers are used to specify the format of a gutter.
553 The values of the variables `default-gutter', `top-gutter',
554 `left-gutter', `right-gutter', and `bottom-gutter' are always
557 Valid gutter instantiators are called "gutter descriptors"
558 and are lists of vectors. See `default-gutter' for a description
563 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
568 Helper for invalidating the real specifier when default
569 specifier caching changes
572 recompute_overlaying_specifier (Lisp_Object real_one[4])
574 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
575 Fset_specifier_dirty_flag (real_one[pos]);
579 gutter_specs_changed (Lisp_Object specifier, struct window *w,
583 GUTTER_POS_LOOP (pos)
585 w->real_gutter_size[pos] = w->gutter_size[pos];
586 if (EQ (w->real_gutter_size[pos], Qautodetect)
587 && !NILP (w->gutter_visible_p[pos]))
589 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
593 MARK_WINDOWS_CHANGED (w);
597 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
600 recompute_overlaying_specifier (Vgutter);
604 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
608 GUTTER_POS_LOOP (pos)
610 w->real_gutter_size[pos] = w->gutter_size[pos];
611 if (EQ (w->real_gutter_size[pos], Qautodetect)
612 && !NILP (w->gutter_visible_p[pos]))
614 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
619 MARK_WINDOWS_CHANGED (w);
623 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
626 recompute_overlaying_specifier (Vgutter_size);
630 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
634 recompute_overlaying_specifier (Vgutter_border_width);
638 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
642 recompute_overlaying_specifier (Vgutter_visible_p);
646 DECLARE_SPECIFIER_TYPE (gutter_size);
647 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
648 DEFINE_SPECIFIER_TYPE (gutter_size);
651 gutter_size_validate (Lisp_Object instantiator)
653 if (NILP (instantiator))
656 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
657 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
660 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
661 Return non-nil if OBJECT is a gutter-size specifier.
665 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
668 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
669 Ensure that all gutters are correctly showing their gutter specifier.
673 Lisp_Object devcons, concons;
675 DEVICE_LOOP_NO_BREAK (devcons, concons)
677 struct device *d = XDEVICE (XCAR (devcons));
680 DEVICE_FRAME_LOOP (frmcons, d)
682 struct frame *f = XFRAME (XCAR (frmcons));
684 if (FRAME_REPAINT_P (f))
686 update_frame_gutters (f);
690 /* We now call the output_end routine for tty frames. We delay
691 doing so in order to avoid cursor flicker. So much for 100%
693 if (DEVICE_TTY_P (d))
694 DEVMETH (d, output_end, (d));
701 init_frame_gutters (struct frame *f)
704 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
705 /* We are here as far in frame creation so cached specifiers are
706 already recomputed, and possibly modified by resource
707 initialization. We need to recalculate autodetected gutters. */
708 GUTTER_POS_LOOP (pos)
710 w->real_gutter_size[pos] = w->gutter_size[pos];
711 if (EQ (w->gutter_size[pos], Qautodetect)
712 && !NILP (w->gutter_visible_p[pos]))
714 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
716 MARK_WINDOWS_CHANGED (w);
722 syms_of_gutter (void)
724 DEFSUBR (Fgutter_specifier_p);
725 DEFSUBR (Fgutter_size_specifier_p);
726 DEFSUBR (Fset_default_gutter_position);
727 DEFSUBR (Fdefault_gutter_position);
728 DEFSUBR (Fgutter_pixel_height);
729 DEFSUBR (Fgutter_pixel_width);
730 DEFSUBR (Fredisplay_gutter_area);
732 defsymbol (&Qgutter_size, "gutter-size");
736 vars_of_gutter (void)
738 staticpro (&Vdefault_gutter_position);
739 Vdefault_gutter_position = Qtop;
745 specifier_type_create_gutter (void)
747 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
749 SPECIFIER_HAS_METHOD (gutter, validate);
750 SPECIFIER_HAS_METHOD (gutter, after_change);
752 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
754 SPECIFIER_HAS_METHOD (gutter_size, validate);
758 reinit_specifier_type_create_gutter (void)
760 REINITIALIZE_SPECIFIER_TYPE (gutter);
761 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
765 specifier_vars_of_gutter (void)
769 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
770 Specifier for a fallback gutter.
771 Use `set-specifier' to change this.
773 The position of this gutter is specified in the function
774 `default-gutter-position'. If the corresponding position-specific
775 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
776 does not specify a gutter in a particular domain (usually a window),
777 then the value of `default-gutter' in that domain, if any, will be
780 Note that the gutter at any particular position will not be
781 displayed unless its visibility flag is true and its thickness
782 \(width or height, depending on orientation) is non-zero. The
783 visibility is controlled by the specifiers `top-gutter-visible-p',
784 `bottom-gutter-visible-p', `left-gutter-visible-p', and
785 `right-gutter-visible-p', and the thickness is controlled by the
786 specifiers `top-gutter-height', `bottom-gutter-height',
787 `left-gutter-width', and `right-gutter-width'.
789 Note that one of the four visibility specifiers inherits from
790 `default-gutter-visibility' and one of the four thickness
791 specifiers inherits from either `default-gutter-width' or
792 `default-gutter-height' (depending on orientation), just
793 like for the gutter description specifiers (e.g. `top-gutter')
796 Therefore, if you are setting `default-gutter', you should control
797 the visibility and thickness using `default-gutter-visible-p',
798 `default-gutter-width', and `default-gutter-height', rather than
799 using position-specific specifiers. That way, you will get sane
800 behavior if the user changes the default gutter position.
802 The gutter value should be a string or nil. You can attach extents and
803 glyphs to the string and hence display glyphs and text in other fonts
808 Vdefault_gutter = Fmake_specifier (Qgutter);
809 /* #### It would be even nicer if the specifier caching
810 automatically knew about specifier fallbacks, so we didn't
811 have to do it ourselves. */
812 set_specifier_caching (Vdefault_gutter,
813 offsetof (struct window, default_gutter),
814 default_gutter_specs_changed,
817 DEFVAR_SPECIFIER ("top-gutter",
818 &Vgutter[TOP_GUTTER] /*
819 Specifier for the gutter at the top of the frame.
820 Use `set-specifier' to change this.
821 See `default-gutter' for a description of a valid gutter instantiator.
823 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
824 set_specifier_caching (Vgutter[TOP_GUTTER],
825 offsetof (struct window, gutter[TOP_GUTTER]),
826 gutter_specs_changed,
829 DEFVAR_SPECIFIER ("bottom-gutter",
830 &Vgutter[BOTTOM_GUTTER] /*
831 Specifier for the gutter at the bottom of the frame.
832 Use `set-specifier' to change this.
833 See `default-gutter' for a description of a valid gutter instantiator.
835 Note that, unless the `default-gutter-position' is `bottom', by
836 default the height of the bottom gutter (controlled by
837 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
838 displayed even if you provide a value for `bottom-gutter'.
840 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
841 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
842 offsetof (struct window, gutter[BOTTOM_GUTTER]),
843 gutter_specs_changed,
846 DEFVAR_SPECIFIER ("left-gutter",
847 &Vgutter[LEFT_GUTTER] /*
848 Specifier for the gutter at the left edge of the frame.
849 Use `set-specifier' to change this.
850 See `default-gutter' for a description of a valid gutter instantiator.
852 Note that, unless the `default-gutter-position' is `left', by
853 default the height of the left gutter (controlled by
854 `left-gutter-width') is 0; thus, a left gutter will not be
855 displayed even if you provide a value for `left-gutter'.
857 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
858 set_specifier_caching (Vgutter[LEFT_GUTTER],
859 offsetof (struct window, gutter[LEFT_GUTTER]),
860 gutter_specs_changed,
863 DEFVAR_SPECIFIER ("right-gutter",
864 &Vgutter[RIGHT_GUTTER] /*
865 Specifier for the gutter at the right edge of the frame.
866 Use `set-specifier' to change this.
867 See `default-gutter' for a description of a valid gutter instantiator.
869 Note that, unless the `default-gutter-position' is `right', by
870 default the height of the right gutter (controlled by
871 `right-gutter-width') is 0; thus, a right gutter will not be
872 displayed even if you provide a value for `right-gutter'.
874 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
875 set_specifier_caching (Vgutter[RIGHT_GUTTER],
876 offsetof (struct window, 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 offsetof (struct window, default_gutter_height),
917 default_gutter_size_changed_in_window,
920 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
921 *Width of the default gutter, if it's oriented vertically.
922 This is a specifier; use `set-specifier' to change it.
924 See `default-gutter-height' for more information.
926 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
927 set_specifier_caching (Vdefault_gutter_width,
928 offsetof (struct window, default_gutter_width),
929 default_gutter_size_changed_in_window,
932 DEFVAR_SPECIFIER ("top-gutter-height",
933 &Vgutter_size[TOP_GUTTER] /*
934 *Height of the top gutter.
935 This is a specifier; use `set-specifier' to change it.
937 See `default-gutter-height' for more information.
939 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
940 set_specifier_caching (Vgutter_size[TOP_GUTTER],
941 offsetof (struct window, gutter_size[TOP_GUTTER]),
942 gutter_geometry_changed_in_window,
945 DEFVAR_SPECIFIER ("bottom-gutter-height",
946 &Vgutter_size[BOTTOM_GUTTER] /*
947 *Height of the bottom gutter.
948 This is a specifier; use `set-specifier' to change it.
950 See `default-gutter-height' for more information.
952 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
953 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
954 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
955 gutter_geometry_changed_in_window,
958 DEFVAR_SPECIFIER ("left-gutter-width",
959 &Vgutter_size[LEFT_GUTTER] /*
960 *Width of left gutter.
961 This is a specifier; use `set-specifier' to change it.
963 See `default-gutter-height' for more information.
965 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
966 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
967 offsetof (struct window, gutter_size[LEFT_GUTTER]),
968 gutter_geometry_changed_in_window,
971 DEFVAR_SPECIFIER ("right-gutter-width",
972 &Vgutter_size[RIGHT_GUTTER] /*
973 *Width of right gutter.
974 This is a specifier; use `set-specifier' to change it.
976 See `default-gutter-height' for more information.
978 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
979 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
980 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
981 gutter_geometry_changed_in_window,
986 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
988 #ifdef HAVE_X_WINDOWS
989 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
991 #ifdef HAVE_MS_WINDOWS
992 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
993 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
996 set_specifier_fallback (Vdefault_gutter_height, fb);
1000 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1002 #ifdef HAVE_X_WINDOWS
1003 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
1005 #ifdef HAVE_MS_WINDOWS
1006 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1007 fb = Fcons (Fcons (list1 (Qmswindows),
1008 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1011 set_specifier_fallback (Vdefault_gutter_width, fb);
1013 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1014 fb = list1 (Fcons (Qnil, Qzero));
1015 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1016 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1017 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1019 DEFVAR_SPECIFIER ("default-gutter-border-width",
1020 &Vdefault_gutter_border_width /*
1021 *Width of the border around the default gutter.
1022 This is a specifier; use `set-specifier' to change it.
1024 The position of the default gutter is specified by the function
1025 `set-default-gutter-position'. If the corresponding position-specific
1026 gutter border width specifier (e.g. `top-gutter-border-width' if
1027 `default-gutter-position' is 'top) does not specify a border width in a
1028 particular domain (a window or a frame), then the value of
1029 `default-gutter-border-width' in that domain, if any, will be used
1033 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1034 set_specifier_caching (Vdefault_gutter_border_width,
1035 offsetof (struct window, default_gutter_border_width),
1036 default_gutter_border_width_changed_in_window,
1039 DEFVAR_SPECIFIER ("top-gutter-border-width",
1040 &Vgutter_border_width[TOP_GUTTER] /*
1041 *Border width of the top gutter.
1042 This is a specifier; use `set-specifier' to change it.
1044 See `default-gutter-height' for more information.
1046 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1047 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1048 offsetof (struct window,
1049 gutter_border_width[TOP_GUTTER]),
1050 gutter_geometry_changed_in_window,
1053 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1054 &Vgutter_border_width[BOTTOM_GUTTER] /*
1055 *Border width of the bottom gutter.
1056 This is a specifier; use `set-specifier' to change it.
1058 See `default-gutter-height' for more information.
1060 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1061 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1062 offsetof (struct window,
1063 gutter_border_width[BOTTOM_GUTTER]),
1064 gutter_geometry_changed_in_window,
1067 DEFVAR_SPECIFIER ("left-gutter-border-width",
1068 &Vgutter_border_width[LEFT_GUTTER] /*
1069 *Border width of left gutter.
1070 This is a specifier; use `set-specifier' to change it.
1072 See `default-gutter-height' for more information.
1074 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1075 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1076 offsetof (struct window,
1077 gutter_border_width[LEFT_GUTTER]),
1078 gutter_geometry_changed_in_window,
1081 DEFVAR_SPECIFIER ("right-gutter-border-width",
1082 &Vgutter_border_width[RIGHT_GUTTER] /*
1083 *Border width of right gutter.
1084 This is a specifier; use `set-specifier' to change it.
1086 See `default-gutter-height' for more information.
1088 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1089 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1090 offsetof (struct window,
1091 gutter_border_width[RIGHT_GUTTER]),
1092 gutter_geometry_changed_in_window,
1097 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1099 #ifdef HAVE_X_WINDOWS
1100 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1102 #ifdef HAVE_MS_WINDOWS
1103 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1104 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1107 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1109 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1110 fb = list1 (Fcons (Qnil, Qzero));
1111 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1112 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1113 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1115 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1116 *Whether the default gutter is visible.
1117 This is a specifier; use `set-specifier' to change it.
1119 The position of the default gutter is specified by the function
1120 `set-default-gutter-position'. If the corresponding position-specific
1121 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1122 `default-gutter-position' is 'top) does not specify a visible-p value
1123 in a particular domain (a window or a frame), then the value of
1124 `default-gutter-visible-p' in that domain, if any, will be used
1127 `default-gutter-visible-p' and all of the position-specific gutter
1128 visibility specifiers have a fallback value of true.
1130 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean);
1131 set_specifier_caching (Vdefault_gutter_visible_p,
1132 offsetof (struct window,
1133 default_gutter_visible_p),
1134 default_gutter_visible_p_changed_in_window,
1137 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1138 &Vgutter_visible_p[TOP_GUTTER] /*
1139 *Whether the top gutter is visible.
1140 This is a specifier; use `set-specifier' to change it.
1142 See `default-gutter-visible-p' for more information.
1144 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean);
1145 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1146 offsetof (struct window,
1147 gutter_visible_p[TOP_GUTTER]),
1148 gutter_geometry_changed_in_window,
1151 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1152 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1153 *Whether the bottom gutter is visible.
1154 This is a specifier; use `set-specifier' to change it.
1156 See `default-gutter-visible-p' for more information.
1158 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean);
1159 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1160 offsetof (struct window,
1161 gutter_visible_p[BOTTOM_GUTTER]),
1162 gutter_geometry_changed_in_window,
1165 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1166 &Vgutter_visible_p[LEFT_GUTTER] /*
1167 *Whether the left gutter is visible.
1168 This is a specifier; use `set-specifier' to change it.
1170 See `default-gutter-visible-p' for more information.
1172 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean);
1173 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1174 offsetof (struct window,
1175 gutter_visible_p[LEFT_GUTTER]),
1176 gutter_geometry_changed_in_window,
1179 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1180 &Vgutter_visible_p[RIGHT_GUTTER] /*
1181 *Whether the right gutter is visible.
1182 This is a specifier; use `set-specifier' to change it.
1184 See `default-gutter-visible-p' for more information.
1186 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean);
1187 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1188 offsetof (struct window,
1189 gutter_visible_p[RIGHT_GUTTER]),
1190 gutter_geometry_changed_in_window,
1193 /* initially, top inherits from default; this can be
1194 changed with `set-default-gutter-position'. */
1195 fb = list1 (Fcons (Qnil, Qt));
1196 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1197 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1198 Vdefault_gutter_visible_p);
1199 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1200 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1201 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);