1 /* Gutter implementation.
2 Copyright (C) 1999, 2000 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;
50 Lisp_Object Qgutter_visible;
51 Lisp_Object Qdefault_gutter_position_changed_hook;
53 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
58 (frame)->top_gutter_was_visible = flag; \
61 (frame)->bottom_gutter_was_visible = flag; \
64 (frame)->left_gutter_was_visible = flag; \
67 (frame)->right_gutter_was_visible = flag; \
74 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
79 return frame->top_gutter_was_visible;
81 return frame->bottom_gutter_was_visible;
83 return frame->left_gutter_was_visible;
85 return frame->right_gutter_was_visible;
93 frame_topmost_window (struct frame *f)
95 Lisp_Object w = FRAME_ROOT_WINDOW (f);
98 while (!NILP (XWINDOW (w)->vchild))
100 w = XWINDOW (w)->vchild;
102 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
109 frame_bottommost_window (struct frame *f)
111 Lisp_Object w = FRAME_ROOT_WINDOW (f);
114 while (!NILP (XWINDOW (w)->vchild))
116 w = XWINDOW (w)->vchild;
117 while (!NILP (XWINDOW (w)->next))
119 w = XWINDOW (w)->next;
122 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
129 frame_leftmost_window (struct frame *f)
131 Lisp_Object w = FRAME_ROOT_WINDOW (f);
134 while (!NILP (XWINDOW (w)->hchild))
136 w = XWINDOW (w)->hchild;
138 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
144 frame_rightmost_window (struct frame *f)
146 Lisp_Object w = FRAME_ROOT_WINDOW (f);
149 while (!NILP (XWINDOW (w)->hchild))
151 w = XWINDOW (w)->hchild;
152 while (!NILP (XWINDOW (w)->next))
154 w = XWINDOW (w)->next;
157 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
162 /* calculate the coordinates of a gutter for the current frame and
163 selected window. we have to be careful in calculating this as we
164 need to use *two* windows, the currently selected window will give
165 us the actual height, width and contents of the gutter, but if we
166 use this for calculating the gutter positions we run into trouble
167 if it is not the window nearest the gutter. Instead we predetermine
168 the nearest window and then use that.*/
170 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
171 int *width, int *height)
174 * bot = XWINDOW (frame_bottommost_window (f));
175 /* The top and bottom gutters take precedence over the left and
180 *x = FRAME_LEFT_BORDER_END (f);
181 *y = FRAME_TOP_BORDER_END (f);
182 *width = FRAME_RIGHT_BORDER_START (f)
183 - FRAME_LEFT_BORDER_END (f);
184 *height = FRAME_TOP_GUTTER_BOUNDS (f);
188 *x = FRAME_LEFT_BORDER_END (f);
189 *y = WINDOW_BOTTOM (bot);
190 *width = FRAME_RIGHT_BORDER_START (f)
191 - FRAME_LEFT_BORDER_END (f);
192 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f);
196 *x = FRAME_LEFT_BORDER_END (f);
197 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
198 *width = FRAME_LEFT_GUTTER_BOUNDS (f);
199 *height = WINDOW_BOTTOM (bot)
200 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
204 *x = FRAME_RIGHT_BORDER_START (f)
205 - FRAME_RIGHT_GUTTER_BOUNDS (f);
206 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
207 *width = FRAME_RIGHT_GUTTER_BOUNDS (f);
208 *height = WINDOW_BOTTOM (bot)
209 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
217 /* Convert the gutter specifier into something we can actually
219 static Lisp_Object construct_window_gutter_spec (struct window* w,
222 Lisp_Object rest, *args;
224 Lisp_Object gutter = RAW_WINDOW_GUTTER (w, pos);
226 if (STRINGP (gutter) || NILP (gutter))
229 GET_LIST_LENGTH (gutter, nargs);
230 args = alloca_array (Lisp_Object, nargs >> 1);
233 for (rest = gutter; !NILP (rest); rest = XCDR (XCDR (rest)))
235 /* We only put things in the real gutter that are declared to be
237 if (!CONSP (WINDOW_GUTTER_VISIBLE (w, pos))
239 !NILP (Fmemq (XCAR (rest), WINDOW_GUTTER_VISIBLE (w, pos))))
241 args [nargs++] = XCAR (XCDR (rest));
245 return Fconcat (nargs, args);
249 output_gutter (struct frame *f, enum gutter_pos pos, int force)
252 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
253 struct device *d = XDEVICE (f->device);
254 struct window* w = XWINDOW (window);
255 int x, y, width, height, ypos;
256 int line, border_width;
258 display_line_dynarr* ddla, *cdla;
259 struct display_line *dl;
262 if (!WINDOW_LIVE_P (w))
265 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
266 findex = get_builtin_face_cache_index (w, Vwidget_face);
268 if (!f->current_display_lines[pos])
269 f->current_display_lines[pos] = Dynarr_new (display_line);
270 if (!f->desired_display_lines[pos])
271 f->desired_display_lines[pos] = Dynarr_new (display_line);
273 ddla = f->desired_display_lines[pos];
274 cdla = f->current_display_lines[pos];
275 cdla_len = Dynarr_length (cdla);
277 XSETFRAME (frame, f);
279 get_gutter_coords (f, pos, &x, &y, &width, &height);
280 /* generate some display lines */
281 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
282 x + border_width, y + border_width,
283 width - 2 * border_width,
284 height - 2 * border_width, ddla, 0, findex);
286 /* We only output the gutter if we think something of significance
287 has changed. This is, for example, because redisplay can cause
288 new face cache elements to get added causing compare_runes to
289 fail because the findex for a particular face has changed. */
290 if (force || f->faces_changed || f->frame_changed ||
291 f->gutter_changed || f->glyphs_changed ||
292 f->size_changed || f->subwindows_changed ||
293 w->windows_changed || f->windows_structure_changed ||
294 cdla_len != Dynarr_length (ddla) ||
295 (f->extents_changed && w->gutter_extent_modiff[pos]))
298 printf ("gutter redisplay triggered by %s\n", force ? "force" :
299 f->faces_changed ? "f->faces_changed" :
300 f->frame_changed ? "f->frame_changed" :
301 f->gutter_changed ? "f->gutter_changed" :
302 f->glyphs_changed ? "f->glyphs_changed" :
303 f->size_changed ? "f->size_changed" :
304 f->subwindows_changed ? "f->subwindows_changed" :
305 w->windows_changed ? "w->windows_changed" :
306 f->windows_structure_changed ? "f->windows_structure_changed" :
307 cdla_len != Dynarr_length (ddla) ? "different display structures" :
308 f->extents_changed && w->gutter_extent_modiff[pos] ?
309 "f->extents_changed && w->gutter_extent_modiff[pos]" : "<null>");
311 /* Output each line. */
312 for (line = 0; line < Dynarr_length (ddla); line++)
314 output_display_line (w, cdla, ddla, line, -1, -1);
317 /* If the number of display lines has shrunk, adjust. */
318 if (cdla_len > Dynarr_length (ddla))
320 Dynarr_length (cdla) = Dynarr_length (ddla);
323 /* grab coordinates of last line and blank after it. */
324 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
325 ypos = dl->ypos + dl->descent - dl->clip;
326 redisplay_clear_region (window, findex, x + border_width , ypos,
327 width - 2 * border_width, height - (ypos - y) - border_width);
328 /* bevel the gutter area if so desired */
329 if (border_width != 0)
331 MAYBE_DEVMETH (d, bevel_area,
332 (w, findex, x, y, width, height, border_width,
333 EDGE_ALL, EDGE_BEVEL_OUT));
338 /* Nothing of significance happened so sync the display line
340 for (line = 0; line < Dynarr_length (ddla); line++)
342 sync_display_line_structs (w, line, 1, cdla, ddla);
346 w->gutter_extent_modiff [pos] = 0;
349 /* Sizing gutters is a pain so we try and help the user by detemining
350 what height will accommodate all lines. This is useless on left and
351 right gutters as we always have a maximal number of lines. */
353 calculate_gutter_size (struct window *w, enum gutter_pos pos)
355 struct frame* f = XFRAME (WINDOW_FRAME (w));
357 display_line_dynarr* ddla;
358 struct display_line *dl;
360 /* we cannot autodetect gutter sizes for the left and right as there
361 is no reasonable metric to use */
362 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
363 /* degenerate case */
364 if (NILP (RAW_WINDOW_GUTTER (w, pos))
371 /* Redisplay code that we use relies on GC not happening. Make it
373 count = specpdl_depth ();
374 record_unwind_protect (restore_gc_inhibit,
375 make_int (gc_currently_forbidden));
376 gc_currently_forbidden = 1;
378 ddla = Dynarr_new (display_line);
379 /* generate some display lines */
380 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
381 FRAME_LEFT_BORDER_END (f),
383 FRAME_RIGHT_BORDER_START (f)
384 - FRAME_LEFT_BORDER_END (f),
388 /* Let GC happen again. */
389 unbind_to (count, Qnil);
391 /* grab coordinates of last line */
392 if (Dynarr_length (ddla))
394 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
395 ypos = dl->ypos + dl->descent - dl->clip;
396 free_display_lines (ddla);
397 return make_int (ypos);
401 free_display_lines (ddla);
407 clear_gutter (struct frame *f, enum gutter_pos pos)
409 int x, y, width, height;
410 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
411 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
413 get_gutter_coords (f, pos, &x, &y, &width, &height);
415 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
417 redisplay_clear_region (window, findex, x, y, width, height);
420 /* #### I don't currently believe that redisplay needs to mark the
421 glyphs in its structures since these will always be referenced from
422 somewhere else. However, I'm not sure enough to stake my life on it
423 at this point, so we do the safe thing. */
425 /* See the comment in image_instantiate_cache_result as to why marking
426 the glyph will also mark the image_instance. */
428 mark_gutters (struct frame* f)
431 GUTTER_POS_LOOP (pos)
433 if (f->current_display_lines[pos])
434 mark_redisplay_structs (f->current_display_lines[pos]);
435 /* #### Do we really need to mark the desired lines? */
436 if (f->desired_display_lines[pos])
437 mark_redisplay_structs (f->desired_display_lines[pos]);
441 /* This is called by extent_changed_for_redisplay, so that redisplay
442 knows exactly what extents have changed. */
444 gutter_extent_signal_changed_region_maybe (Lisp_Object obj,
445 Bufpos start, Bufpos end)
447 /* #### Start and end are currently ignored but could be used by a
448 more optimal gutter redisplay. We currently loop over all frames
449 here, this could be optimized. */
450 Lisp_Object frmcons, devcons, concons;
452 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
454 struct frame *f = XFRAME (XCAR (frmcons));
456 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
457 struct window* w = XWINDOW (window);
459 GUTTER_POS_LOOP (pos)
461 if (EQ (WINDOW_GUTTER (w, pos), obj))
463 w->gutter_extent_modiff[pos]++;
469 /* We have to change the gutter geometry separately to the gutter
470 update since it needs to occur outside of redisplay proper. */
472 update_frame_gutter_geometry (struct frame *f)
474 if (f->gutter_changed || f->windows_structure_changed)
478 /* If the gutter geometry has changed then re-layout the
479 frame. If we are in display there is almost no point in doing
480 anything else since the frame size changes will be delayed
481 until we are out of redisplay proper. */
482 GUTTER_POS_LOOP (pos)
484 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos])
487 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
489 change_frame_size (f, height, width, 0);
494 GUTTER_POS_LOOP (pos)
496 /* Mark sizes as up-to-date. */
497 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
503 update_frame_gutters (struct frame *f)
505 if (f->faces_changed || f->frame_changed ||
506 f->gutter_changed || f->glyphs_changed ||
507 f->size_changed || f->subwindows_changed ||
508 f->windows_changed || f->windows_structure_changed ||
513 /* We don't actually care about these when outputting the gutter
514 so locally disable them. */
515 int local_clip_changed = f->clip_changed;
516 int local_buffers_changed = f->buffers_changed;
518 f->buffers_changed = 0;
521 GUTTER_POS_LOOP (pos)
523 if (FRAME_GUTTER_VISIBLE (f, pos))
524 output_gutter (f, pos, 0);
526 else if (gutter_was_visible (f, pos))
527 clear_gutter (f, pos);
530 f->clip_changed = local_clip_changed;
531 f->buffers_changed = local_buffers_changed;
532 f->gutter_changed = 0;
537 reset_gutter_display_lines (struct frame* f)
540 GUTTER_POS_LOOP (pos)
542 if (f->current_display_lines[pos])
543 Dynarr_reset (f->current_display_lines[pos]);
548 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
549 int width, int height)
551 int g_x, g_y, g_width, g_height;
553 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
555 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
557 if (((x + width) < g_x) || (x > (g_x + g_width)))
560 /* #### optimize this - redrawing the whole gutter for every expose
561 is very expensive. We reset the current display lines because if
562 they're being exposed they are no longer current. */
563 reset_gutter_display_lines (f);
565 /* Even if none of the gutter is in the area, the blank region at
566 the very least must be because the first thing we did is verify
567 that some portion of the gutter is in the exposed region. */
568 output_gutter (f, pos, 1);
572 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
576 GUTTER_POS_LOOP (pos)
578 if (FRAME_GUTTER_VISIBLE (f, pos))
579 redraw_exposed_gutter (f, pos, x, y, width, height);
584 free_frame_gutters (struct frame *f)
587 GUTTER_POS_LOOP (pos)
589 if (f->current_display_lines[pos])
591 free_display_lines (f->current_display_lines[pos]);
592 f->current_display_lines[pos] = 0;
594 if (f->desired_display_lines[pos])
596 free_display_lines (f->desired_display_lines[pos]);
597 f->desired_display_lines[pos] = 0;
602 static enum gutter_pos
603 decode_gutter_position (Lisp_Object position)
605 if (EQ (position, Qtop)) return TOP_GUTTER;
606 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
607 if (EQ (position, Qleft)) return LEFT_GUTTER;
608 if (EQ (position, Qright)) return RIGHT_GUTTER;
609 signal_simple_error ("Invalid gutter position", position);
611 return TOP_GUTTER; /* not reached */
614 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
615 Set the position that the `default-gutter' will be displayed at.
616 Valid positions are 'top, 'bottom, 'left and 'right.
617 See `default-gutter-position'.
621 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
622 enum gutter_pos new = decode_gutter_position (position);
626 /* The following calls will automatically cause the dirty
627 flags to be set; we delay frame size changes to avoid
628 lots of frame flickering. */
629 /* #### I think this should be GC protected. -sb */
630 hold_frame_size_changes ();
631 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
632 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
633 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
634 set_specifier_fallback (Vgutter_size[new],
635 new == TOP_GUTTER || new == BOTTOM_GUTTER
636 ? Vdefault_gutter_height
637 : Vdefault_gutter_width);
638 set_specifier_fallback (Vgutter_border_width[cur],
639 list1 (Fcons (Qnil, Qzero)));
640 set_specifier_fallback (Vgutter_border_width[new],
641 Vdefault_gutter_border_width);
642 /* We don't realy want the left and right gutters to default to
644 set_specifier_fallback (Vgutter_visible_p[cur],
645 cur == TOP_GUTTER || cur == BOTTOM_GUTTER ?
646 list1 (Fcons (Qnil, Qt))
647 : list1 (Fcons (Qnil, Qnil)));
648 set_specifier_fallback (Vgutter_visible_p[new],
649 Vdefault_gutter_visible_p);
651 Vdefault_gutter_position = position;
652 unhold_frame_size_changes ();
655 run_hook (Qdefault_gutter_position_changed_hook);
660 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
661 Return the position that the `default-gutter' will be displayed at.
662 The `default-gutter' will only be displayed here if the corresponding
663 position-specific gutter specifier does not provide a value.
667 return Vdefault_gutter_position;
670 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
671 Return the pixel width of the gutter at POS in LOCALE.
672 POS defaults to the default gutter position. LOCALE defaults to
677 int x, y, width, height;
678 enum gutter_pos p = TOP_GUTTER;
679 struct frame *f = decode_frame (FW_FRAME (locale));
682 pos = Vdefault_gutter_position;
683 p = decode_gutter_position (pos);
685 get_gutter_coords (f, p, &x, &y, &width, &height);
686 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
688 return make_int (width);
691 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
692 Return the pixel height of the gutter at POS in LOCALE.
693 POS defaults to the default gutter position. LOCALE defaults to
698 int x, y, width, height;
699 enum gutter_pos p = TOP_GUTTER;
700 struct frame *f = decode_frame (FW_FRAME (locale));
703 pos = Vdefault_gutter_position;
704 p = decode_gutter_position (pos);
706 get_gutter_coords (f, p, &x, &y, &width, &height);
707 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
709 return make_int (height);
712 DEFINE_SPECIFIER_TYPE (gutter);
715 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
721 gutter_validate (Lisp_Object instantiator)
723 if (NILP (instantiator))
726 /* Must be a string or a plist. */
727 if (!STRINGP (instantiator) && NILP (Fvalid_plist_p (instantiator)))
728 signal_simple_error ("Gutter spec must be string, plist or nil", instantiator);
730 if (!STRINGP (instantiator))
734 for (rest = instantiator; !NILP (rest); rest = XCDR (XCDR (rest)))
736 if (!SYMBOLP (XCAR (rest))
737 || !STRINGP (XCAR (XCDR (rest))))
738 signal_simple_error ("Gutter plist spec must contain strings", instantiator);
743 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
744 Return non-nil if OBJECT is a gutter specifier.
745 Gutter specifiers are used to specify the format of a gutter.
746 The values of the variables `default-gutter', `top-gutter',
747 `left-gutter', `right-gutter', and `bottom-gutter' are always
750 Valid gutter instantiators are called "gutter descriptors" and are
751 either strings or property-lists of strings. See `default-gutter' for
752 a description of the exact format.
756 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
761 Helper for invalidating the real specifier when default
762 specifier caching changes
765 recompute_overlaying_specifier (Lisp_Object real_one[4])
767 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
768 Fset_specifier_dirty_flag (real_one[pos]);
772 gutter_specs_changed (Lisp_Object specifier, struct window *w,
773 Lisp_Object oldval, enum gutter_pos pos)
775 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
776 w->real_gutter_size[pos] = w->gutter_size[pos];
778 if (EQ (w->real_gutter_size[pos], Qautodetect)
779 && !NILP (w->gutter_visible_p[pos]))
781 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
784 MARK_MODELINE_CHANGED;
785 MARK_WINDOWS_CHANGED (w);
788 /* We define all of these so we can access which actual gutter changed. */
790 top_gutter_specs_changed (Lisp_Object specifier, struct window *w,
793 gutter_specs_changed (specifier, w, oldval, TOP_GUTTER);
797 bottom_gutter_specs_changed (Lisp_Object specifier, struct window *w,
800 gutter_specs_changed (specifier, w, oldval, BOTTOM_GUTTER);
804 left_gutter_specs_changed (Lisp_Object specifier, struct window *w,
807 gutter_specs_changed (specifier, w, oldval, LEFT_GUTTER);
811 right_gutter_specs_changed (Lisp_Object specifier, struct window *w,
814 gutter_specs_changed (specifier, w, oldval, RIGHT_GUTTER);
818 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
821 recompute_overlaying_specifier (Vgutter);
825 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
829 GUTTER_POS_LOOP (pos)
831 w->real_gutter_size[pos] = w->gutter_size[pos];
832 if (EQ (w->real_gutter_size[pos], Qautodetect)
833 && !NILP (w->gutter_visible_p[pos]))
835 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
840 MARK_MODELINE_CHANGED;
841 MARK_WINDOWS_CHANGED (w);
845 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
848 recompute_overlaying_specifier (Vgutter_size);
852 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
856 recompute_overlaying_specifier (Vgutter_border_width);
860 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
864 recompute_overlaying_specifier (Vgutter_visible_p);
865 /* Need to reconstruct the gutter specifier as it is affected by the
867 recompute_overlaying_specifier (Vgutter);
871 DECLARE_SPECIFIER_TYPE (gutter_size);
872 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
873 DEFINE_SPECIFIER_TYPE (gutter_size);
876 gutter_size_validate (Lisp_Object instantiator)
878 if (NILP (instantiator))
881 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
882 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
885 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
886 Return non-nil if OBJECT is a gutter-size specifier.
888 Gutter-size specifiers are used to specify the size of a gutter. The
889 values of the variables `default-gutter-size', `top-gutter-size',
890 `left-gutter-size', `right-gutter-size', and `bottom-gutter-size' are
891 always gutter-size specifiers.
893 Valid gutter-size instantiators are either integers or the special
894 symbol 'autodetect. If a gutter-size is set to 'autodetect them the
895 size of the gutter will be adjusted to just accomodate the gutters
896 contents. 'autodetect only works for top and bottom gutters.
900 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
903 DECLARE_SPECIFIER_TYPE (gutter_visible);
904 #define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible)
905 DEFINE_SPECIFIER_TYPE (gutter_visible);
908 gutter_visible_validate (Lisp_Object instantiator)
910 if (NILP (instantiator))
913 if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator))
914 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
917 if (CONSP (instantiator))
921 EXTERNAL_LIST_LOOP (rest, instantiator)
923 if (!SYMBOLP (XCAR (rest)))
924 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
930 DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /*
931 Return non-nil if OBJECT is a gutter-visible specifier.
933 Gutter-visible specifiers are used to specify the visibility of a
934 gutter. The values of the variables `default-gutter-visible-p',
935 `top-gutter-visible-p', `left-gutter-visible-p',
936 `right-gutter-visible-p', and `bottom-gutter-visible-p' are always
937 gutter-visible specifiers.
939 Valid gutter-visible instantiators are t, nil or a list of symbols.
940 If a gutter-visible instantiator is set to a list of symbols, and the
941 correspondong gutter specification is a property-list strings, then
942 elements of the gutter specification will only be visible if the
943 corresponding symbol occurs in the gutter-visible instantiator.
947 return GUTTER_VISIBLE_SPECIFIERP (object) ? Qt : Qnil;
950 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
951 Ensure that all gutters are correctly showing their gutter specifier.
955 Lisp_Object devcons, concons;
957 DEVICE_LOOP_NO_BREAK (devcons, concons)
959 struct device *d = XDEVICE (XCAR (devcons));
962 DEVICE_FRAME_LOOP (frmcons, d)
964 struct frame *f = XFRAME (XCAR (frmcons));
966 /* Sequence is quite important here. We not only want to
967 redisplay the gutter area but we also want to flush any
968 frame size changes out so that the gutter redisplay happens
969 in a kosha environment.
971 This is not only so that things look right but so that
972 glyph redisplay optimization kicks in, by default display
973 lines will be completely re-output if
974 f->windows_structure_changed is 1, and this is true if
975 frame size changes haven't been flushed out. Once frame
976 size changes have been flushed out we then need to
977 redisplay the frame in order to flush out pending window
979 update_frame_gutter_geometry (f);
981 if (f->windows_structure_changed)
982 redisplay_frame (f, 1);
983 else if (FRAME_REPAINT_P (f))
985 /* We have to be "in display" when we output the gutter
987 hold_frame_size_changes ();
988 update_frame_gutters (f);
989 unhold_one_frame_size_changes (f);
992 /* We now call the output_end routine for tty frames. We delay
993 doing so in order to avoid cursor flicker. So much for 100%
995 if (DEVICE_TTY_P (d))
996 DEVMETH (d, output_end, (d));
998 d->gutter_changed = 0;
1001 /* This is so that further changes to the gutters will trigger redisplay. */
1002 gutter_changed_set = 0;
1009 init_frame_gutters (struct frame *f)
1011 enum gutter_pos pos;
1012 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
1013 /* We are here as far in frame creation so cached specifiers are
1014 already recomputed, and possibly modified by resource
1015 initialization. We need to recalculate autodetected gutters. */
1016 GUTTER_POS_LOOP (pos)
1018 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
1019 w->real_gutter_size[pos] = w->gutter_size[pos];
1020 if (EQ (w->gutter_size[pos], Qautodetect)
1021 && !NILP (w->gutter_visible_p[pos]))
1023 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
1024 MARK_GUTTER_CHANGED;
1025 MARK_WINDOWS_CHANGED (w);
1029 /* Keep a record of the current sizes of things. */
1030 GUTTER_POS_LOOP (pos)
1032 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
1037 syms_of_gutter (void)
1039 DEFSUBR (Fgutter_specifier_p);
1040 DEFSUBR (Fgutter_size_specifier_p);
1041 DEFSUBR (Fgutter_visible_specifier_p);
1042 DEFSUBR (Fset_default_gutter_position);
1043 DEFSUBR (Fdefault_gutter_position);
1044 DEFSUBR (Fgutter_pixel_height);
1045 DEFSUBR (Fgutter_pixel_width);
1046 DEFSUBR (Fredisplay_gutter_area);
1048 defsymbol (&Qgutter_size, "gutter-size");
1049 defsymbol (&Qgutter_visible, "gutter-visible");
1050 defsymbol (&Qdefault_gutter_position_changed_hook,
1051 "default-gutter-position-changed");
1055 vars_of_gutter (void)
1057 staticpro (&Vdefault_gutter_position);
1058 Vdefault_gutter_position = Qtop;
1064 specifier_type_create_gutter (void)
1066 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
1067 SPECIFIER_HAS_METHOD (gutter, validate);
1068 SPECIFIER_HAS_METHOD (gutter, after_change);
1070 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
1071 SPECIFIER_HAS_METHOD (gutter_size, validate);
1073 INITIALIZE_SPECIFIER_TYPE (gutter_visible, "gutter-visible", "gutter-visible-specifier-p");
1074 SPECIFIER_HAS_METHOD (gutter_visible, validate);
1078 reinit_specifier_type_create_gutter (void)
1080 REINITIALIZE_SPECIFIER_TYPE (gutter);
1081 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
1082 REINITIALIZE_SPECIFIER_TYPE (gutter_visible);
1086 specifier_vars_of_gutter (void)
1090 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
1091 Specifier for a fallback gutter.
1092 Use `set-specifier' to change this.
1094 The position of this gutter is specified in the function
1095 `default-gutter-position'. If the corresponding position-specific
1096 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
1097 does not specify a gutter in a particular domain (usually a window),
1098 then the value of `default-gutter' in that domain, if any, will be
1101 Note that the gutter at any particular position will not be
1102 displayed unless its visibility flag is true and its thickness
1103 \(width or height, depending on orientation) is non-zero. The
1104 visibility is controlled by the specifiers `top-gutter-visible-p',
1105 `bottom-gutter-visible-p', `left-gutter-visible-p', and
1106 `right-gutter-visible-p', and the thickness is controlled by the
1107 specifiers `top-gutter-height', `bottom-gutter-height',
1108 `left-gutter-width', and `right-gutter-width'.
1110 Note that one of the four visibility specifiers inherits from
1111 `default-gutter-visibility' and one of the four thickness
1112 specifiers inherits from either `default-gutter-width' or
1113 `default-gutter-height' (depending on orientation), just
1114 like for the gutter description specifiers (e.g. `top-gutter')
1117 Therefore, if you are setting `default-gutter', you should control
1118 the visibility and thickness using `default-gutter-visible-p',
1119 `default-gutter-width', and `default-gutter-height', rather than
1120 using position-specific specifiers. That way, you will get sane
1121 behavior if the user changes the default gutter position.
1123 The gutter value should be a string, a property list of strings or
1124 nil. You can attach extents and glyphs to the string and hence display
1125 glyphs and text in other fonts in the gutter area. If the gutter value
1126 is a property list then the strings will be concatenated together
1127 before being displayed. */ );
1129 Vdefault_gutter = Fmake_specifier (Qgutter);
1130 /* #### It would be even nicer if the specifier caching
1131 automatically knew about specifier fallbacks, so we didn't
1132 have to do it ourselves. */
1133 set_specifier_caching (Vdefault_gutter,
1134 offsetof (struct window, default_gutter),
1135 default_gutter_specs_changed,
1138 DEFVAR_SPECIFIER ("top-gutter",
1139 &Vgutter[TOP_GUTTER] /*
1140 Specifier for the gutter at the top of the frame.
1141 Use `set-specifier' to change this.
1142 See `default-gutter' for a description of a valid gutter instantiator.
1144 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
1145 set_specifier_caching (Vgutter[TOP_GUTTER],
1146 offsetof (struct window, gutter[TOP_GUTTER]),
1147 top_gutter_specs_changed,
1150 DEFVAR_SPECIFIER ("bottom-gutter",
1151 &Vgutter[BOTTOM_GUTTER] /*
1152 Specifier for the gutter at the bottom of the frame.
1153 Use `set-specifier' to change this.
1154 See `default-gutter' for a description of a valid gutter instantiator.
1156 Note that, unless the `default-gutter-position' is `bottom', by
1157 default the height of the bottom gutter (controlled by
1158 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
1159 displayed even if you provide a value for `bottom-gutter'.
1161 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
1162 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
1163 offsetof (struct window, gutter[BOTTOM_GUTTER]),
1164 bottom_gutter_specs_changed,
1167 DEFVAR_SPECIFIER ("left-gutter",
1168 &Vgutter[LEFT_GUTTER] /*
1169 Specifier for the gutter at the left edge of the frame.
1170 Use `set-specifier' to change this.
1171 See `default-gutter' for a description of a valid gutter instantiator.
1173 Note that, unless the `default-gutter-position' is `left', by
1174 default the height of the left gutter (controlled by
1175 `left-gutter-width') is 0; thus, a left gutter will not be
1176 displayed even if you provide a value for `left-gutter'.
1178 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
1179 set_specifier_caching (Vgutter[LEFT_GUTTER],
1180 offsetof (struct window, gutter[LEFT_GUTTER]),
1181 left_gutter_specs_changed,
1184 DEFVAR_SPECIFIER ("right-gutter",
1185 &Vgutter[RIGHT_GUTTER] /*
1186 Specifier for the gutter at the right edge of the frame.
1187 Use `set-specifier' to change this.
1188 See `default-gutter' for a description of a valid gutter instantiator.
1190 Note that, unless the `default-gutter-position' is `right', by
1191 default the height of the right gutter (controlled by
1192 `right-gutter-width') is 0; thus, a right gutter will not be
1193 displayed even if you provide a value for `right-gutter'.
1195 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
1196 set_specifier_caching (Vgutter[RIGHT_GUTTER],
1197 offsetof (struct window, gutter[RIGHT_GUTTER]),
1198 right_gutter_specs_changed,
1201 /* initially, top inherits from default; this can be
1202 changed with `set-default-gutter-position'. */
1203 fb = list1 (Fcons (Qnil, Qnil));
1204 set_specifier_fallback (Vdefault_gutter, fb);
1205 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
1206 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
1207 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
1208 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
1210 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
1211 *Height of the default gutter, if it's oriented horizontally.
1212 This is a specifier; use `set-specifier' to change it.
1214 The position of the default gutter is specified by the function
1215 `set-default-gutter-position'. If the corresponding position-specific
1216 gutter thickness specifier (e.g. `top-gutter-height' if
1217 `default-gutter-position' is 'top) does not specify a thickness in a
1218 particular domain (a window or a frame), then the value of
1219 `default-gutter-height' or `default-gutter-width' (depending on the
1220 gutter orientation) in that domain, if any, will be used instead.
1222 Note that `default-gutter-height' is only used when
1223 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
1224 is only used when `default-gutter-position' is 'left or 'right.
1226 Note that all of the position-specific gutter thickness specifiers
1227 have a fallback value of zero when they do not correspond to the
1228 default gutter. Therefore, you will have to set a non-zero thickness
1229 value if you want a position-specific gutter to be displayed.
1231 If you set the height to 'autodetect the size of the gutter will be
1232 calculated to be large enough to hold the contents of the gutter. This
1235 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
1236 set_specifier_caching (Vdefault_gutter_height,
1237 offsetof (struct window, default_gutter_height),
1238 default_gutter_size_changed_in_window,
1241 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
1242 *Width of the default gutter, if it's oriented vertically.
1243 This is a specifier; use `set-specifier' to change it.
1245 See `default-gutter-height' for more information.
1247 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
1248 set_specifier_caching (Vdefault_gutter_width,
1249 offsetof (struct window, default_gutter_width),
1250 default_gutter_size_changed_in_window,
1253 DEFVAR_SPECIFIER ("top-gutter-height",
1254 &Vgutter_size[TOP_GUTTER] /*
1255 *Height of the top gutter.
1256 This is a specifier; use `set-specifier' to change it.
1258 See `default-gutter-height' for more information.
1260 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
1261 set_specifier_caching (Vgutter_size[TOP_GUTTER],
1262 offsetof (struct window, gutter_size[TOP_GUTTER]),
1263 gutter_geometry_changed_in_window, 0, 0);
1265 DEFVAR_SPECIFIER ("bottom-gutter-height",
1266 &Vgutter_size[BOTTOM_GUTTER] /*
1267 *Height of the bottom gutter.
1268 This is a specifier; use `set-specifier' to change it.
1270 See `default-gutter-height' for more information.
1272 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
1273 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
1274 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
1275 gutter_geometry_changed_in_window, 0, 0);
1277 DEFVAR_SPECIFIER ("left-gutter-width",
1278 &Vgutter_size[LEFT_GUTTER] /*
1279 *Width of left gutter.
1280 This is a specifier; use `set-specifier' to change it.
1282 See `default-gutter-height' for more information.
1284 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1285 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
1286 offsetof (struct window, gutter_size[LEFT_GUTTER]),
1287 gutter_geometry_changed_in_window, 0, 0);
1289 DEFVAR_SPECIFIER ("right-gutter-width",
1290 &Vgutter_size[RIGHT_GUTTER] /*
1291 *Width of right gutter.
1292 This is a specifier; use `set-specifier' to change it.
1294 See `default-gutter-height' for more information.
1296 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1297 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
1298 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
1299 gutter_geometry_changed_in_window, 0, 0);
1303 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1305 #ifdef HAVE_X_WINDOWS
1306 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
1308 #ifdef HAVE_MS_WINDOWS
1309 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
1310 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1313 set_specifier_fallback (Vdefault_gutter_height, fb);
1317 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1319 #ifdef HAVE_X_WINDOWS
1320 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
1322 #ifdef HAVE_MS_WINDOWS
1323 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1324 fb = Fcons (Fcons (list1 (Qmswindows),
1325 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1328 set_specifier_fallback (Vdefault_gutter_width, fb);
1330 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1331 fb = list1 (Fcons (Qnil, Qzero));
1332 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1333 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1334 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1336 DEFVAR_SPECIFIER ("default-gutter-border-width",
1337 &Vdefault_gutter_border_width /*
1338 *Width of the border around the default gutter.
1339 This is a specifier; use `set-specifier' to change it.
1341 The position of the default gutter is specified by the function
1342 `set-default-gutter-position'. If the corresponding position-specific
1343 gutter border width specifier (e.g. `top-gutter-border-width' if
1344 `default-gutter-position' is 'top) does not specify a border width in a
1345 particular domain (a window or a frame), then the value of
1346 `default-gutter-border-width' in that domain, if any, will be used
1350 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1351 set_specifier_caching (Vdefault_gutter_border_width,
1352 offsetof (struct window, default_gutter_border_width),
1353 default_gutter_border_width_changed_in_window,
1356 DEFVAR_SPECIFIER ("top-gutter-border-width",
1357 &Vgutter_border_width[TOP_GUTTER] /*
1358 *Border width of the top gutter.
1359 This is a specifier; use `set-specifier' to change it.
1361 See `default-gutter-height' for more information.
1363 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1364 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1365 offsetof (struct window,
1366 gutter_border_width[TOP_GUTTER]),
1367 gutter_geometry_changed_in_window, 0, 0);
1369 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1370 &Vgutter_border_width[BOTTOM_GUTTER] /*
1371 *Border width of the bottom gutter.
1372 This is a specifier; use `set-specifier' to change it.
1374 See `default-gutter-height' for more information.
1376 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1377 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1378 offsetof (struct window,
1379 gutter_border_width[BOTTOM_GUTTER]),
1380 gutter_geometry_changed_in_window, 0, 0);
1382 DEFVAR_SPECIFIER ("left-gutter-border-width",
1383 &Vgutter_border_width[LEFT_GUTTER] /*
1384 *Border width of left gutter.
1385 This is a specifier; use `set-specifier' to change it.
1387 See `default-gutter-height' for more information.
1389 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1390 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1391 offsetof (struct window,
1392 gutter_border_width[LEFT_GUTTER]),
1393 gutter_geometry_changed_in_window, 0, 0);
1395 DEFVAR_SPECIFIER ("right-gutter-border-width",
1396 &Vgutter_border_width[RIGHT_GUTTER] /*
1397 *Border width of right gutter.
1398 This is a specifier; use `set-specifier' to change it.
1400 See `default-gutter-height' for more information.
1402 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1403 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1404 offsetof (struct window,
1405 gutter_border_width[RIGHT_GUTTER]),
1406 gutter_geometry_changed_in_window, 0, 0);
1410 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1412 #ifdef HAVE_X_WINDOWS
1413 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1415 #ifdef HAVE_MS_WINDOWS
1416 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1417 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1420 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1422 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1423 fb = list1 (Fcons (Qnil, Qzero));
1424 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1425 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1426 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1428 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1429 *Whether the default gutter is visible.
1430 This is a specifier; use `set-specifier' to change it.
1432 The position of the default gutter is specified by the function
1433 `set-default-gutter-position'. If the corresponding position-specific
1434 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1435 `default-gutter-position' is 'top) does not specify a visible-p value
1436 in a particular domain (a window or a frame), then the value of
1437 `default-gutter-visible-p' in that domain, if any, will be used
1440 `default-gutter-visible-p' and all of the position-specific gutter
1441 visibility specifiers have a fallback value of true.
1443 Vdefault_gutter_visible_p = Fmake_specifier (Qgutter_visible);
1444 set_specifier_caching (Vdefault_gutter_visible_p,
1445 offsetof (struct window,
1446 default_gutter_visible_p),
1447 default_gutter_visible_p_changed_in_window,
1450 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1451 &Vgutter_visible_p[TOP_GUTTER] /*
1452 *Whether the top gutter is visible.
1453 This is a specifier; use `set-specifier' to change it.
1455 See `default-gutter-visible-p' for more information.
1457 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qgutter_visible);
1458 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1459 offsetof (struct window,
1460 gutter_visible_p[TOP_GUTTER]),
1461 top_gutter_specs_changed, 0, 0);
1463 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1464 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1465 *Whether the bottom gutter is visible.
1466 This is a specifier; use `set-specifier' to change it.
1468 See `default-gutter-visible-p' for more information.
1470 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_visible);
1471 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1472 offsetof (struct window,
1473 gutter_visible_p[BOTTOM_GUTTER]),
1474 bottom_gutter_specs_changed, 0, 0);
1476 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1477 &Vgutter_visible_p[LEFT_GUTTER] /*
1478 *Whether the left gutter is visible.
1479 This is a specifier; use `set-specifier' to change it.
1481 See `default-gutter-visible-p' for more information.
1483 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qgutter_visible);
1484 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1485 offsetof (struct window,
1486 gutter_visible_p[LEFT_GUTTER]),
1487 left_gutter_specs_changed, 0, 0);
1489 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1490 &Vgutter_visible_p[RIGHT_GUTTER] /*
1491 *Whether the right gutter is visible.
1492 This is a specifier; use `set-specifier' to change it.
1494 See `default-gutter-visible-p' for more information.
1496 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qgutter_visible);
1497 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1498 offsetof (struct window,
1499 gutter_visible_p[RIGHT_GUTTER]),
1500 right_gutter_specs_changed, 0, 0);
1502 /* initially, top inherits from default; this can be
1503 changed with `set-default-gutter-position'. */
1504 fb = list1 (Fcons (Qnil, Qt));
1505 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1506 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1507 Vdefault_gutter_visible_p);
1508 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1509 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1510 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);