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);
340 /* #### I don't currently believe that redisplay needs to mark the
341 glyphs in its structures since these will always be referenced from
342 somewhere else. However, I'm not sure enough to stake my life on it
343 at this point, so we do the safe thing. */
345 /* See the comment in image_instantiate_cache_result as to why marking
346 the glyph will also mark the image_instance. */
348 mark_gutters (struct frame* f)
350 if (f->current_display_lines)
351 mark_redisplay_structs (f->current_display_lines);
352 if (f->desired_display_lines)
353 mark_redisplay_structs (f->desired_display_lines);
357 update_frame_gutters (struct frame *f)
359 if (f->gutter_changed || f->clear ||
360 f->glyphs_changed || f->subwindows_changed ||
361 f->windows_changed || f->windows_structure_changed ||
362 f->extents_changed || f->faces_changed)
366 /* We don't actually care about these when outputting the gutter
367 so locally disable them. */
368 int local_clip_changed = f->clip_changed;
369 int local_buffers_changed = f->buffers_changed;
371 f->buffers_changed = 0;
374 GUTTER_POS_LOOP (pos)
376 if (FRAME_GUTTER_VISIBLE (f, pos))
377 output_gutter (f, pos);
378 else if (gutter_was_visible (f, pos))
379 clear_gutter (f, pos);
381 f->clip_changed = local_clip_changed;
382 f->buffers_changed = local_buffers_changed;
383 f->gutter_changed = 0;
388 reset_gutter_display_lines (struct frame* f)
390 if (f->current_display_lines)
391 Dynarr_reset (f->current_display_lines);
395 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
396 int width, int height)
398 int g_x, g_y, g_width, g_height;
400 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
402 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
404 if (((x + width) < g_x) || (x > (g_x + g_width)))
407 /* #### optimize this - redrawing the whole gutter for every expose
408 is very expensive. We reset the current display lines because if
409 they're being exposed they are no longer current. */
410 reset_gutter_display_lines (f);
412 /* Even if none of the gutter is in the area, the blank region at
413 the very least must be because the first thing we did is verify
414 that some portion of the gutter is in the exposed region. */
415 output_gutter (f, pos);
419 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
423 GUTTER_POS_LOOP (pos)
425 if (FRAME_GUTTER_VISIBLE (f, pos))
426 redraw_exposed_gutter (f, pos, x, y, width, height);
431 free_frame_gutters (struct frame *f)
433 if (f->current_display_lines)
435 free_display_lines (f->current_display_lines);
436 f->current_display_lines = 0;
438 if (f->desired_display_lines)
440 free_display_lines (f->desired_display_lines);
441 f->desired_display_lines = 0;
445 static enum gutter_pos
446 decode_gutter_position (Lisp_Object position)
448 if (EQ (position, Qtop)) return TOP_GUTTER;
449 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
450 if (EQ (position, Qleft)) return LEFT_GUTTER;
451 if (EQ (position, Qright)) return RIGHT_GUTTER;
452 signal_simple_error ("Invalid gutter position", position);
454 return TOP_GUTTER; /* not reached */
457 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
458 Set the position that the `default-gutter' will be displayed at.
459 Valid positions are 'top, 'bottom, 'left and 'right.
460 See `default-gutter-position'.
464 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
465 enum gutter_pos new = decode_gutter_position (position);
469 /* The following calls will automatically cause the dirty
470 flags to be set; we delay frame size changes to avoid
471 lots of frame flickering. */
472 /* #### I think this should be GC protected. -sb */
473 hold_frame_size_changes ();
474 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
475 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
476 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
477 set_specifier_fallback (Vgutter_size[new],
478 new == TOP_GUTTER || new == BOTTOM_GUTTER
479 ? Vdefault_gutter_height
480 : Vdefault_gutter_width);
481 set_specifier_fallback (Vgutter_border_width[cur],
482 list1 (Fcons (Qnil, Qzero)));
483 set_specifier_fallback (Vgutter_border_width[new],
484 Vdefault_gutter_border_width);
485 set_specifier_fallback (Vgutter_visible_p[cur],
486 list1 (Fcons (Qnil, Qt)));
487 set_specifier_fallback (Vgutter_visible_p[new],
488 Vdefault_gutter_visible_p);
489 Vdefault_gutter_position = position;
490 unhold_frame_size_changes ();
496 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
497 Return the position that the `default-gutter' will be displayed at.
498 The `default-gutter' will only be displayed here if the corresponding
499 position-specific gutter specifier does not provide a value.
503 return Vdefault_gutter_position;
506 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
507 Return the pixel width 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 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
524 return make_int (width);
527 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
528 Return the pixel height of the gutter at POS in LOCALE.
529 POS defaults to the default gutter position. LOCALE defaults to
534 int x, y, width, height;
535 enum gutter_pos p = TOP_GUTTER;
536 struct frame *f = decode_frame (FW_FRAME (locale));
539 pos = Vdefault_gutter_position;
540 p = decode_gutter_position (pos);
542 get_gutter_coords (f, p, &x, &y, &width, &height);
543 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
545 return make_int (height);
548 DEFINE_SPECIFIER_TYPE (gutter);
551 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
557 gutter_validate (Lisp_Object instantiator)
559 if (NILP (instantiator))
562 if (!STRINGP (instantiator))
563 signal_simple_error ("Gutter spec must be string or nil", instantiator);
566 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
567 Return non-nil if OBJECT is a gutter specifier.
568 Gutter specifiers are used to specify the format of a gutter.
569 The values of the variables `default-gutter', `top-gutter',
570 `left-gutter', `right-gutter', and `bottom-gutter' are always
573 Valid gutter instantiators are called "gutter descriptors"
574 and are lists of vectors. See `default-gutter' for a description
579 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
584 Helper for invalidating the real specifier when default
585 specifier caching changes
588 recompute_overlaying_specifier (Lisp_Object real_one[4])
590 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
591 Fset_specifier_dirty_flag (real_one[pos]);
595 gutter_specs_changed (Lisp_Object specifier, struct window *w,
599 GUTTER_POS_LOOP (pos)
601 w->real_gutter_size[pos] = w->gutter_size[pos];
602 if (EQ (w->real_gutter_size[pos], Qautodetect)
603 && !NILP (w->gutter_visible_p[pos]))
605 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
609 MARK_WINDOWS_CHANGED (w);
613 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
616 recompute_overlaying_specifier (Vgutter);
620 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
624 GUTTER_POS_LOOP (pos)
626 w->real_gutter_size[pos] = w->gutter_size[pos];
627 if (EQ (w->real_gutter_size[pos], Qautodetect)
628 && !NILP (w->gutter_visible_p[pos]))
630 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
635 MARK_WINDOWS_CHANGED (w);
639 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
642 recompute_overlaying_specifier (Vgutter_size);
646 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
650 recompute_overlaying_specifier (Vgutter_border_width);
654 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
658 recompute_overlaying_specifier (Vgutter_visible_p);
662 DECLARE_SPECIFIER_TYPE (gutter_size);
663 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
664 DEFINE_SPECIFIER_TYPE (gutter_size);
667 gutter_size_validate (Lisp_Object instantiator)
669 if (NILP (instantiator))
672 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
673 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
676 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
677 Return non-nil if OBJECT is a gutter-size specifier.
681 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
684 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
685 Ensure that all gutters are correctly showing their gutter specifier.
689 Lisp_Object devcons, concons;
691 DEVICE_LOOP_NO_BREAK (devcons, concons)
693 struct device *d = XDEVICE (XCAR (devcons));
696 DEVICE_FRAME_LOOP (frmcons, d)
698 struct frame *f = XFRAME (XCAR (frmcons));
700 if (FRAME_REPAINT_P (f))
702 update_frame_gutters (f);
706 /* We now call the output_end routine for tty frames. We delay
707 doing so in order to avoid cursor flicker. So much for 100%
709 if (DEVICE_TTY_P (d))
710 DEVMETH (d, output_end, (d));
717 init_frame_gutters (struct frame *f)
720 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
721 /* We are here as far in frame creation so cached specifiers are
722 already recomputed, and possibly modified by resource
723 initialization. We need to recalculate autodetected gutters. */
724 GUTTER_POS_LOOP (pos)
726 w->real_gutter_size[pos] = w->gutter_size[pos];
727 if (EQ (w->gutter_size[pos], Qautodetect)
728 && !NILP (w->gutter_visible_p[pos]))
730 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
732 MARK_WINDOWS_CHANGED (w);
738 syms_of_gutter (void)
740 DEFSUBR (Fgutter_specifier_p);
741 DEFSUBR (Fgutter_size_specifier_p);
742 DEFSUBR (Fset_default_gutter_position);
743 DEFSUBR (Fdefault_gutter_position);
744 DEFSUBR (Fgutter_pixel_height);
745 DEFSUBR (Fgutter_pixel_width);
746 DEFSUBR (Fredisplay_gutter_area);
748 defsymbol (&Qgutter_size, "gutter-size");
752 vars_of_gutter (void)
754 staticpro (&Vdefault_gutter_position);
755 Vdefault_gutter_position = Qtop;
761 specifier_type_create_gutter (void)
763 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
765 SPECIFIER_HAS_METHOD (gutter, validate);
766 SPECIFIER_HAS_METHOD (gutter, after_change);
768 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
770 SPECIFIER_HAS_METHOD (gutter_size, validate);
774 reinit_specifier_type_create_gutter (void)
776 REINITIALIZE_SPECIFIER_TYPE (gutter);
777 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
781 specifier_vars_of_gutter (void)
785 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
786 Specifier for a fallback gutter.
787 Use `set-specifier' to change this.
789 The position of this gutter is specified in the function
790 `default-gutter-position'. If the corresponding position-specific
791 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
792 does not specify a gutter in a particular domain (usually a window),
793 then the value of `default-gutter' in that domain, if any, will be
796 Note that the gutter at any particular position will not be
797 displayed unless its visibility flag is true and its thickness
798 \(width or height, depending on orientation) is non-zero. The
799 visibility is controlled by the specifiers `top-gutter-visible-p',
800 `bottom-gutter-visible-p', `left-gutter-visible-p', and
801 `right-gutter-visible-p', and the thickness is controlled by the
802 specifiers `top-gutter-height', `bottom-gutter-height',
803 `left-gutter-width', and `right-gutter-width'.
805 Note that one of the four visibility specifiers inherits from
806 `default-gutter-visibility' and one of the four thickness
807 specifiers inherits from either `default-gutter-width' or
808 `default-gutter-height' (depending on orientation), just
809 like for the gutter description specifiers (e.g. `top-gutter')
812 Therefore, if you are setting `default-gutter', you should control
813 the visibility and thickness using `default-gutter-visible-p',
814 `default-gutter-width', and `default-gutter-height', rather than
815 using position-specific specifiers. That way, you will get sane
816 behavior if the user changes the default gutter position.
818 The gutter value should be a string or nil. You can attach extents and
819 glyphs to the string and hence display glyphs and text in other fonts
824 Vdefault_gutter = Fmake_specifier (Qgutter);
825 /* #### It would be even nicer if the specifier caching
826 automatically knew about specifier fallbacks, so we didn't
827 have to do it ourselves. */
828 set_specifier_caching (Vdefault_gutter,
829 offsetof (struct window, default_gutter),
830 default_gutter_specs_changed,
833 DEFVAR_SPECIFIER ("top-gutter",
834 &Vgutter[TOP_GUTTER] /*
835 Specifier for the gutter at the top of the frame.
836 Use `set-specifier' to change this.
837 See `default-gutter' for a description of a valid gutter instantiator.
839 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
840 set_specifier_caching (Vgutter[TOP_GUTTER],
841 offsetof (struct window, gutter[TOP_GUTTER]),
842 gutter_specs_changed,
845 DEFVAR_SPECIFIER ("bottom-gutter",
846 &Vgutter[BOTTOM_GUTTER] /*
847 Specifier for the gutter at the bottom of the frame.
848 Use `set-specifier' to change this.
849 See `default-gutter' for a description of a valid gutter instantiator.
851 Note that, unless the `default-gutter-position' is `bottom', by
852 default the height of the bottom gutter (controlled by
853 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
854 displayed even if you provide a value for `bottom-gutter'.
856 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
857 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
858 offsetof (struct window, gutter[BOTTOM_GUTTER]),
859 gutter_specs_changed,
862 DEFVAR_SPECIFIER ("left-gutter",
863 &Vgutter[LEFT_GUTTER] /*
864 Specifier for the gutter at the left 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 `left', by
869 default the height of the left gutter (controlled by
870 `left-gutter-width') is 0; thus, a left gutter will not be
871 displayed even if you provide a value for `left-gutter'.
873 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
874 set_specifier_caching (Vgutter[LEFT_GUTTER],
875 offsetof (struct window, gutter[LEFT_GUTTER]),
876 gutter_specs_changed,
879 DEFVAR_SPECIFIER ("right-gutter",
880 &Vgutter[RIGHT_GUTTER] /*
881 Specifier for the gutter at the right edge of the frame.
882 Use `set-specifier' to change this.
883 See `default-gutter' for a description of a valid gutter instantiator.
885 Note that, unless the `default-gutter-position' is `right', by
886 default the height of the right gutter (controlled by
887 `right-gutter-width') is 0; thus, a right gutter will not be
888 displayed even if you provide a value for `right-gutter'.
890 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
891 set_specifier_caching (Vgutter[RIGHT_GUTTER],
892 offsetof (struct window, gutter[RIGHT_GUTTER]),
893 gutter_specs_changed,
896 /* initially, top inherits from default; this can be
897 changed with `set-default-gutter-position'. */
898 fb = list1 (Fcons (Qnil, Qnil));
899 set_specifier_fallback (Vdefault_gutter, fb);
900 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
901 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
902 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
903 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
905 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
906 *Height of the default gutter, if it's oriented horizontally.
907 This is a specifier; use `set-specifier' to change it.
909 The position of the default gutter is specified by the function
910 `set-default-gutter-position'. If the corresponding position-specific
911 gutter thickness specifier (e.g. `top-gutter-height' if
912 `default-gutter-position' is 'top) does not specify a thickness in a
913 particular domain (a window or a frame), then the value of
914 `default-gutter-height' or `default-gutter-width' (depending on the
915 gutter orientation) in that domain, if any, will be used instead.
917 Note that `default-gutter-height' is only used when
918 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
919 is only used when `default-gutter-position' is 'left or 'right.
921 Note that all of the position-specific gutter thickness specifiers
922 have a fallback value of zero when they do not correspond to the
923 default gutter. Therefore, you will have to set a non-zero thickness
924 value if you want a position-specific gutter to be displayed.
926 If you set the height to 'autodetect the size of the gutter will be
927 calculated to be large enough to hold the contents of the gutter. This
930 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
931 set_specifier_caching (Vdefault_gutter_height,
932 offsetof (struct window, default_gutter_height),
933 default_gutter_size_changed_in_window,
936 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
937 *Width of the default gutter, if it's oriented vertically.
938 This is a specifier; use `set-specifier' to change it.
940 See `default-gutter-height' for more information.
942 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
943 set_specifier_caching (Vdefault_gutter_width,
944 offsetof (struct window, default_gutter_width),
945 default_gutter_size_changed_in_window,
948 DEFVAR_SPECIFIER ("top-gutter-height",
949 &Vgutter_size[TOP_GUTTER] /*
950 *Height of the top gutter.
951 This is a specifier; use `set-specifier' to change it.
953 See `default-gutter-height' for more information.
955 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
956 set_specifier_caching (Vgutter_size[TOP_GUTTER],
957 offsetof (struct window, gutter_size[TOP_GUTTER]),
958 gutter_geometry_changed_in_window,
961 DEFVAR_SPECIFIER ("bottom-gutter-height",
962 &Vgutter_size[BOTTOM_GUTTER] /*
963 *Height of the bottom gutter.
964 This is a specifier; use `set-specifier' to change it.
966 See `default-gutter-height' for more information.
968 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
969 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
970 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
971 gutter_geometry_changed_in_window,
974 DEFVAR_SPECIFIER ("left-gutter-width",
975 &Vgutter_size[LEFT_GUTTER] /*
976 *Width of left gutter.
977 This is a specifier; use `set-specifier' to change it.
979 See `default-gutter-height' for more information.
981 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
982 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
983 offsetof (struct window, gutter_size[LEFT_GUTTER]),
984 gutter_geometry_changed_in_window,
987 DEFVAR_SPECIFIER ("right-gutter-width",
988 &Vgutter_size[RIGHT_GUTTER] /*
989 *Width of right gutter.
990 This is a specifier; use `set-specifier' to change it.
992 See `default-gutter-height' for more information.
994 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
995 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
996 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
997 gutter_geometry_changed_in_window,
1002 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1004 #ifdef HAVE_X_WINDOWS
1005 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
1007 #ifdef HAVE_MS_WINDOWS
1008 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
1009 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1012 set_specifier_fallback (Vdefault_gutter_height, fb);
1016 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1018 #ifdef HAVE_X_WINDOWS
1019 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
1021 #ifdef HAVE_MS_WINDOWS
1022 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1023 fb = Fcons (Fcons (list1 (Qmswindows),
1024 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1027 set_specifier_fallback (Vdefault_gutter_width, fb);
1029 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1030 fb = list1 (Fcons (Qnil, Qzero));
1031 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1032 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1033 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1035 DEFVAR_SPECIFIER ("default-gutter-border-width",
1036 &Vdefault_gutter_border_width /*
1037 *Width of the border around the default gutter.
1038 This is a specifier; use `set-specifier' to change it.
1040 The position of the default gutter is specified by the function
1041 `set-default-gutter-position'. If the corresponding position-specific
1042 gutter border width specifier (e.g. `top-gutter-border-width' if
1043 `default-gutter-position' is 'top) does not specify a border width in a
1044 particular domain (a window or a frame), then the value of
1045 `default-gutter-border-width' in that domain, if any, will be used
1049 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1050 set_specifier_caching (Vdefault_gutter_border_width,
1051 offsetof (struct window, default_gutter_border_width),
1052 default_gutter_border_width_changed_in_window,
1055 DEFVAR_SPECIFIER ("top-gutter-border-width",
1056 &Vgutter_border_width[TOP_GUTTER] /*
1057 *Border width of the top gutter.
1058 This is a specifier; use `set-specifier' to change it.
1060 See `default-gutter-height' for more information.
1062 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1063 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1064 offsetof (struct window,
1065 gutter_border_width[TOP_GUTTER]),
1066 gutter_geometry_changed_in_window,
1069 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1070 &Vgutter_border_width[BOTTOM_GUTTER] /*
1071 *Border width of the bottom gutter.
1072 This is a specifier; use `set-specifier' to change it.
1074 See `default-gutter-height' for more information.
1076 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1077 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1078 offsetof (struct window,
1079 gutter_border_width[BOTTOM_GUTTER]),
1080 gutter_geometry_changed_in_window,
1083 DEFVAR_SPECIFIER ("left-gutter-border-width",
1084 &Vgutter_border_width[LEFT_GUTTER] /*
1085 *Border width of left gutter.
1086 This is a specifier; use `set-specifier' to change it.
1088 See `default-gutter-height' for more information.
1090 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1091 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1092 offsetof (struct window,
1093 gutter_border_width[LEFT_GUTTER]),
1094 gutter_geometry_changed_in_window,
1097 DEFVAR_SPECIFIER ("right-gutter-border-width",
1098 &Vgutter_border_width[RIGHT_GUTTER] /*
1099 *Border width of right gutter.
1100 This is a specifier; use `set-specifier' to change it.
1102 See `default-gutter-height' for more information.
1104 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1105 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1106 offsetof (struct window,
1107 gutter_border_width[RIGHT_GUTTER]),
1108 gutter_geometry_changed_in_window,
1113 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1115 #ifdef HAVE_X_WINDOWS
1116 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1118 #ifdef HAVE_MS_WINDOWS
1119 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1120 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1123 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1125 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1126 fb = list1 (Fcons (Qnil, Qzero));
1127 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1128 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1129 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1131 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1132 *Whether the default gutter is visible.
1133 This is a specifier; use `set-specifier' to change it.
1135 The position of the default gutter is specified by the function
1136 `set-default-gutter-position'. If the corresponding position-specific
1137 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1138 `default-gutter-position' is 'top) does not specify a visible-p value
1139 in a particular domain (a window or a frame), then the value of
1140 `default-gutter-visible-p' in that domain, if any, will be used
1143 `default-gutter-visible-p' and all of the position-specific gutter
1144 visibility specifiers have a fallback value of true.
1146 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean);
1147 set_specifier_caching (Vdefault_gutter_visible_p,
1148 offsetof (struct window,
1149 default_gutter_visible_p),
1150 default_gutter_visible_p_changed_in_window,
1153 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1154 &Vgutter_visible_p[TOP_GUTTER] /*
1155 *Whether the top gutter is visible.
1156 This is a specifier; use `set-specifier' to change it.
1158 See `default-gutter-visible-p' for more information.
1160 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean);
1161 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1162 offsetof (struct window,
1163 gutter_visible_p[TOP_GUTTER]),
1164 gutter_geometry_changed_in_window,
1167 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1168 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1169 *Whether the bottom gutter is visible.
1170 This is a specifier; use `set-specifier' to change it.
1172 See `default-gutter-visible-p' for more information.
1174 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean);
1175 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1176 offsetof (struct window,
1177 gutter_visible_p[BOTTOM_GUTTER]),
1178 gutter_geometry_changed_in_window,
1181 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1182 &Vgutter_visible_p[LEFT_GUTTER] /*
1183 *Whether the left gutter is visible.
1184 This is a specifier; use `set-specifier' to change it.
1186 See `default-gutter-visible-p' for more information.
1188 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean);
1189 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1190 offsetof (struct window,
1191 gutter_visible_p[LEFT_GUTTER]),
1192 gutter_geometry_changed_in_window,
1195 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1196 &Vgutter_visible_p[RIGHT_GUTTER] /*
1197 *Whether the right gutter is visible.
1198 This is a specifier; use `set-specifier' to change it.
1200 See `default-gutter-visible-p' for more information.
1202 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean);
1203 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1204 offsetof (struct window,
1205 gutter_visible_p[RIGHT_GUTTER]),
1206 gutter_geometry_changed_in_window,
1209 /* initially, top inherits from default; this can be
1210 changed with `set-default-gutter-position'. */
1211 fb = list1 (Fcons (Qnil, Qt));
1212 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1213 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1214 Vdefault_gutter_visible_p);
1215 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1216 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1217 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);