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;
54 update_gutter_geometry (struct frame *f, enum gutter_pos pos);
56 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
61 (frame)->top_gutter_was_visible = flag; \
64 (frame)->bottom_gutter_was_visible = flag; \
67 (frame)->left_gutter_was_visible = flag; \
70 (frame)->right_gutter_was_visible = flag; \
77 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
82 return frame->top_gutter_was_visible;
84 return frame->bottom_gutter_was_visible;
86 return frame->left_gutter_was_visible;
88 return frame->right_gutter_was_visible;
91 return 0; /* To keep the compiler happy */
97 frame_topmost_window (struct frame *f)
99 Lisp_Object w = FRAME_ROOT_WINDOW (f);
102 while (!NILP (XWINDOW (w)->vchild))
104 w = XWINDOW (w)->vchild;
106 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
113 frame_bottommost_window (struct frame *f)
115 Lisp_Object w = FRAME_ROOT_WINDOW (f);
118 while (!NILP (XWINDOW (w)->vchild))
120 w = XWINDOW (w)->vchild;
121 while (!NILP (XWINDOW (w)->next))
123 w = XWINDOW (w)->next;
126 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
133 frame_leftmost_window (struct frame *f)
135 Lisp_Object w = FRAME_ROOT_WINDOW (f);
138 while (!NILP (XWINDOW (w)->hchild))
140 w = XWINDOW (w)->hchild;
142 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
148 frame_rightmost_window (struct frame *f)
150 Lisp_Object w = FRAME_ROOT_WINDOW (f);
153 while (!NILP (XWINDOW (w)->hchild))
155 w = XWINDOW (w)->hchild;
156 while (!NILP (XWINDOW (w)->next))
158 w = XWINDOW (w)->next;
161 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild));
166 /* calculate the coordinates of a gutter for the current frame and
167 selected window. we have to be careful in calculating this as we
168 need to use *two* windows, the currently selected window will give
169 us the actual height, width and contents of the gutter, but if we
170 use this for calculating the gutter positions we run into trouble
171 if it is not the window nearest the gutter. Instead we predetermine
172 the nearest window and then use that.*/
174 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
175 int *width, int *height)
178 * bot = XWINDOW (frame_bottommost_window (f));
179 /* The top and bottom gutters take precedence over the left and
184 *x = FRAME_LEFT_BORDER_END (f);
185 *y = FRAME_TOP_BORDER_END (f);
186 *width = FRAME_RIGHT_BORDER_START (f)
187 - FRAME_LEFT_BORDER_END (f);
188 *height = FRAME_TOP_GUTTER_BOUNDS (f);
192 *x = FRAME_LEFT_BORDER_END (f);
193 *y = WINDOW_BOTTOM (bot);
194 *width = FRAME_RIGHT_BORDER_START (f)
195 - FRAME_LEFT_BORDER_END (f);
196 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f);
200 *x = FRAME_LEFT_BORDER_END (f);
201 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
202 *width = FRAME_LEFT_GUTTER_BOUNDS (f);
203 *height = WINDOW_BOTTOM (bot)
204 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
208 *x = FRAME_RIGHT_BORDER_START (f)
209 - FRAME_RIGHT_GUTTER_BOUNDS (f);
210 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
211 *width = FRAME_RIGHT_GUTTER_BOUNDS (f);
212 *height = WINDOW_BOTTOM (bot)
213 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
221 /* Convert the gutter specifier into something we can actually
223 static Lisp_Object construct_window_gutter_spec (struct window* w,
226 Lisp_Object rest, *args;
228 Lisp_Object gutter = RAW_WINDOW_GUTTER (w, pos);
230 if (STRINGP (gutter) || NILP (gutter))
233 GET_LIST_LENGTH (gutter, nargs);
234 args = alloca_array (Lisp_Object, nargs >> 1);
237 for (rest = gutter; !NILP (rest); rest = XCDR (XCDR (rest)))
239 /* We only put things in the real gutter that are declared to be
241 if (!CONSP (WINDOW_GUTTER_VISIBLE (w, pos))
243 !NILP (Fmemq (XCAR (rest), WINDOW_GUTTER_VISIBLE (w, pos))))
245 args [nargs++] = XCAR (XCDR (rest));
249 return Fconcat (nargs, args);
253 output_gutter (struct frame *f, enum gutter_pos pos, int force)
256 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
257 struct device *d = XDEVICE (f->device);
258 struct window* w = XWINDOW (window);
259 int x, y, width, height, ypos;
260 int line, border_width;
262 display_line_dynarr* ddla, *cdla;
263 struct display_line *dl = 0;
266 if (!WINDOW_LIVE_P (w))
269 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
270 findex = get_builtin_face_cache_index (w, Vwidget_face);
272 if (!f->current_display_lines[pos])
273 f->current_display_lines[pos] = Dynarr_new (display_line);
274 if (!f->desired_display_lines[pos])
275 f->desired_display_lines[pos] = Dynarr_new (display_line);
277 ddla = f->desired_display_lines[pos];
278 cdla = f->current_display_lines[pos];
279 cdla_len = Dynarr_length (cdla);
281 XSETFRAME (frame, f);
283 get_gutter_coords (f, pos, &x, &y, &width, &height);
284 /* generate some display lines */
285 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
286 x + border_width, y + border_width,
287 width - 2 * border_width,
288 height - 2 * border_width, ddla, 0, findex);
290 /* We only output the gutter if we think something of significance
291 has changed. This is, for example, because redisplay can cause
292 new face cache elements to get added causing compare_runes to
293 fail because the findex for a particular face has changed. */
294 if (force || f->faces_changed || f->frame_changed ||
295 f->gutter_changed || f->glyphs_changed ||
296 f->size_changed || f->subwindows_changed ||
297 w->windows_changed || f->windows_structure_changed ||
298 cdla_len != Dynarr_length (ddla) ||
299 (f->extents_changed && w->gutter_extent_modiff[pos]))
302 printf ("gutter redisplay triggered by %s\n", force ? "force" :
303 f->faces_changed ? "f->faces_changed" :
304 f->frame_changed ? "f->frame_changed" :
305 f->gutter_changed ? "f->gutter_changed" :
306 f->glyphs_changed ? "f->glyphs_changed" :
307 f->size_changed ? "f->size_changed" :
308 f->subwindows_changed ? "f->subwindows_changed" :
309 w->windows_changed ? "w->windows_changed" :
310 f->windows_structure_changed ? "f->windows_structure_changed" :
311 cdla_len != Dynarr_length (ddla) ? "different display structures" :
312 f->extents_changed && w->gutter_extent_modiff[pos] ?
313 "f->extents_changed && w->gutter_extent_modiff[pos]" : "<null>");
315 /* Output each line. */
316 for (line = 0; line < Dynarr_length (ddla); line++)
318 output_display_line (w, cdla, ddla, line, -1, -1);
321 /* If the number of display lines has shrunk, adjust. */
322 if (cdla_len > Dynarr_length (ddla))
324 Dynarr_length (cdla) = Dynarr_length (ddla);
327 /* grab coordinates of last line and blank after it. */
328 if (Dynarr_length (ddla) > 0)
330 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
331 ypos = dl->ypos + dl->descent - dl->clip;
336 redisplay_clear_region (window, findex, x + border_width , ypos,
337 width - 2 * border_width, height - (ypos - y) - border_width);
338 /* If, for some reason, we have more to display than we have
339 room for, and we are allowed to resize the gutter, then make
340 sure this happens before the next time we try and
341 output. This can happen when face font sizes change. */
342 if (dl && dl->clip > 0 && EQ (w->gutter_size[pos], Qautodetect))
344 /* #### Ideally we would just mark the specifier as dirty
345 and everything else would "just work". Unfortunately we have
346 two problems with this. One is that the specifier cache
347 won't be recalculated unless the specifier code thinks the
348 cached value has actually changed, even though we have
349 marked the specifier as dirty. Additionally, although doing
350 this results in a gutter size change, we never seem to get
351 back into redisplay so that the frame size can be updated. I
352 think this is because we are already in redisplay and later
353 on the frame will be marked as clean. Thus we also have to
354 force a pending recalculation of the frame size. */
355 w->gutter_size[pos] = Qnil;
356 Fset_specifier_dirty_flag (Vgutter_size[pos]);
357 update_gutter_geometry (f, pos);
360 /* bevel the gutter area if so desired */
361 if (border_width != 0)
363 MAYBE_DEVMETH (d, bevel_area,
364 (w, findex, x, y, width, height, border_width,
365 EDGE_ALL, EDGE_BEVEL_OUT));
370 /* Nothing of significance happened so sync the display line
372 for (line = 0; line < Dynarr_length (ddla); line++)
374 sync_display_line_structs (w, line, 1, cdla, ddla);
378 w->gutter_extent_modiff [pos] = 0;
381 /* Sizing gutters is a pain so we try and help the user by detemining
382 what height will accommodate all lines. This is useless on left and
383 right gutters as we always have a maximal number of lines. */
385 calculate_gutter_size (struct window *w, enum gutter_pos pos)
387 struct frame* f = XFRAME (WINDOW_FRAME (w));
389 display_line_dynarr* ddla;
390 struct display_line *dl;
392 /* we cannot autodetect gutter sizes for the left and right as there
393 is no reasonable metric to use */
394 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
395 /* degenerate case */
396 if (NILP (RAW_WINDOW_GUTTER (w, pos))
403 /* Redisplay code that we use relies on GC not happening. Make it
405 count = specpdl_depth ();
406 record_unwind_protect (restore_gc_inhibit,
407 make_int (gc_currently_forbidden));
408 gc_currently_forbidden = 1;
410 ddla = Dynarr_new (display_line);
411 /* generate some display lines */
412 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
413 FRAME_LEFT_BORDER_END (f),
415 FRAME_RIGHT_BORDER_START (f)
416 - FRAME_LEFT_BORDER_END (f),
420 /* Let GC happen again. */
421 unbind_to (count, Qnil);
423 /* grab coordinates of last line */
424 if (Dynarr_length (ddla))
426 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
427 ypos = dl->ypos + dl->descent - dl->clip;
428 free_display_lines (ddla);
429 return make_int (ypos);
433 free_display_lines (ddla);
439 clear_gutter (struct frame *f, enum gutter_pos pos)
441 int x, y, width, height;
442 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
443 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
445 get_gutter_coords (f, pos, &x, &y, &width, &height);
447 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
449 redisplay_clear_region (window, findex, x, y, width, height);
452 /* #### I don't currently believe that redisplay needs to mark the
453 glyphs in its structures since these will always be referenced from
454 somewhere else. However, I'm not sure enough to stake my life on it
455 at this point, so we do the safe thing. */
457 /* See the comment in image_instantiate_cache_result as to why marking
458 the glyph will also mark the image_instance. */
460 mark_gutters (struct frame* f)
463 GUTTER_POS_LOOP (pos)
465 if (f->current_display_lines[pos])
466 mark_redisplay_structs (f->current_display_lines[pos]);
467 /* #### Do we really need to mark the desired lines? */
468 if (f->desired_display_lines[pos])
469 mark_redisplay_structs (f->desired_display_lines[pos]);
473 /* This is called by extent_changed_for_redisplay, so that redisplay
474 knows exactly what extents have changed. */
476 gutter_extent_signal_changed_region_maybe (Lisp_Object obj,
477 Bufpos start, Bufpos end)
479 /* #### Start and end are currently ignored but could be used by a
480 more optimal gutter redisplay. We currently loop over all frames
481 here, this could be optimized. */
482 Lisp_Object frmcons, devcons, concons;
484 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
486 struct frame *f = XFRAME (XCAR (frmcons));
488 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
489 struct window* w = XWINDOW (window);
491 GUTTER_POS_LOOP (pos)
493 if (EQ (WINDOW_GUTTER (w, pos), obj))
495 w->gutter_extent_modiff[pos]++;
501 /* We have to change the gutter geometry separately to the gutter
502 update since it needs to occur outside of redisplay proper. */
504 update_gutter_geometry (struct frame *f, enum gutter_pos pos)
506 /* If the gutter geometry has changed then re-layout the
507 frame. If we are in display there is almost no point in doing
508 anything else since the frame size changes will be delayed
509 until we are out of redisplay proper. */
510 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos])
513 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
515 change_frame_size (f, height, width, 0);
518 /* Mark sizes as up-to-date. */
519 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
523 update_frame_gutter_geometry (struct frame *f)
525 if (f->gutter_changed || f->windows_structure_changed)
529 /* If the gutter geometry has changed then re-layout the
530 frame. If we are in display there is almost no point in doing
531 anything else since the frame size changes will be delayed
532 until we are out of redisplay proper. */
533 GUTTER_POS_LOOP (pos)
535 update_gutter_geometry (f, pos);
541 update_frame_gutters (struct frame *f)
543 if (f->faces_changed || f->frame_changed ||
544 f->gutter_changed || f->glyphs_changed ||
545 f->size_changed || f->subwindows_changed ||
546 f->windows_changed || f->windows_structure_changed ||
551 /* We don't actually care about these when outputting the gutter
552 so locally disable them. */
553 int local_clip_changed = f->clip_changed;
554 int local_buffers_changed = f->buffers_changed;
556 f->buffers_changed = 0;
559 GUTTER_POS_LOOP (pos)
561 if (FRAME_GUTTER_VISIBLE (f, pos))
562 output_gutter (f, pos, 0);
564 else if (gutter_was_visible (f, pos))
565 clear_gutter (f, pos);
568 f->clip_changed = local_clip_changed;
569 f->buffers_changed = local_buffers_changed;
570 f->gutter_changed = 0;
575 reset_gutter_display_lines (struct frame* f)
578 GUTTER_POS_LOOP (pos)
580 if (f->current_display_lines[pos])
581 Dynarr_reset (f->current_display_lines[pos]);
586 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
587 int width, int height)
589 int g_x, g_y, g_width, g_height;
591 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
593 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
595 if (((x + width) < g_x) || (x > (g_x + g_width)))
599 printf ("redrawing gutter after expose %d+%d, %dx%d\n",
600 x, y, width, height);
602 /* #### optimize this - redrawing the whole gutter for every expose
603 is very expensive. We reset the current display lines because if
604 they're being exposed they are no longer current. */
605 reset_gutter_display_lines (f);
607 /* Even if none of the gutter is in the area, the blank region at
608 the very least must be because the first thing we did is verify
609 that some portion of the gutter is in the exposed region. */
610 output_gutter (f, pos, 1);
614 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
619 /* We have to be "in display" when we output the gutter - make it
621 hold_frame_size_changes ();
622 GUTTER_POS_LOOP (pos)
624 if (FRAME_GUTTER_VISIBLE (f, pos))
625 redraw_exposed_gutter (f, pos, x, y, width, height);
627 unhold_one_frame_size_changes (f);
631 free_frame_gutters (struct frame *f)
634 GUTTER_POS_LOOP (pos)
636 if (f->current_display_lines[pos])
638 free_display_lines (f->current_display_lines[pos]);
639 f->current_display_lines[pos] = 0;
641 if (f->desired_display_lines[pos])
643 free_display_lines (f->desired_display_lines[pos]);
644 f->desired_display_lines[pos] = 0;
649 static enum gutter_pos
650 decode_gutter_position (Lisp_Object position)
652 if (EQ (position, Qtop)) return TOP_GUTTER;
653 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
654 if (EQ (position, Qleft)) return LEFT_GUTTER;
655 if (EQ (position, Qright)) return RIGHT_GUTTER;
656 signal_simple_error ("Invalid gutter position", position);
658 return TOP_GUTTER; /* not reached */
661 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
662 Set the position that the `default-gutter' will be displayed at.
663 Valid positions are 'top, 'bottom, 'left and 'right.
664 See `default-gutter-position'.
668 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
669 enum gutter_pos new = decode_gutter_position (position);
673 /* The following calls will automatically cause the dirty
674 flags to be set; we delay frame size changes to avoid
675 lots of frame flickering. */
676 /* #### I think this should be GC protected. -sb */
677 hold_frame_size_changes ();
678 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
679 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
680 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
681 set_specifier_fallback (Vgutter_size[new],
682 new == TOP_GUTTER || new == BOTTOM_GUTTER
683 ? Vdefault_gutter_height
684 : Vdefault_gutter_width);
685 set_specifier_fallback (Vgutter_border_width[cur],
686 list1 (Fcons (Qnil, Qzero)));
687 set_specifier_fallback (Vgutter_border_width[new],
688 Vdefault_gutter_border_width);
689 /* We don't realy want the left and right gutters to default to
691 set_specifier_fallback (Vgutter_visible_p[cur],
692 cur == TOP_GUTTER || cur == BOTTOM_GUTTER ?
693 list1 (Fcons (Qnil, Qt))
694 : list1 (Fcons (Qnil, Qnil)));
695 set_specifier_fallback (Vgutter_visible_p[new],
696 Vdefault_gutter_visible_p);
698 Vdefault_gutter_position = position;
699 unhold_frame_size_changes ();
702 run_hook (Qdefault_gutter_position_changed_hook);
707 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
708 Return the position that the `default-gutter' will be displayed at.
709 The `default-gutter' will only be displayed here if the corresponding
710 position-specific gutter specifier does not provide a value.
714 return Vdefault_gutter_position;
717 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
718 Return the pixel width of the gutter at POS in LOCALE.
719 POS defaults to the default gutter position. LOCALE defaults to
724 int x, y, width, height;
725 enum gutter_pos p = TOP_GUTTER;
726 struct frame *f = decode_frame (FW_FRAME (locale));
729 pos = Vdefault_gutter_position;
730 p = decode_gutter_position (pos);
732 get_gutter_coords (f, p, &x, &y, &width, &height);
733 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
735 return make_int (width);
738 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
739 Return the pixel height of the gutter at POS in LOCALE.
740 POS defaults to the default gutter position. LOCALE defaults to
745 int x, y, width, height;
746 enum gutter_pos p = TOP_GUTTER;
747 struct frame *f = decode_frame (FW_FRAME (locale));
750 pos = Vdefault_gutter_position;
751 p = decode_gutter_position (pos);
753 get_gutter_coords (f, p, &x, &y, &width, &height);
754 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
756 return make_int (height);
759 DEFINE_SPECIFIER_TYPE (gutter);
762 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
768 gutter_validate (Lisp_Object instantiator)
770 if (NILP (instantiator))
773 /* Must be a string or a plist. */
774 if (!STRINGP (instantiator) && NILP (Fvalid_plist_p (instantiator)))
775 signal_simple_error ("Gutter spec must be string, plist or nil", instantiator);
777 if (!STRINGP (instantiator))
781 for (rest = instantiator; !NILP (rest); rest = XCDR (XCDR (rest)))
783 if (!SYMBOLP (XCAR (rest))
784 || !STRINGP (XCAR (XCDR (rest))))
785 signal_simple_error ("Gutter plist spec must contain strings", instantiator);
790 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
791 Return non-nil if OBJECT is a gutter specifier.
793 See `make-gutter-specifier' for a description of possible gutter
798 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
803 Helper for invalidating the real specifier when default
804 specifier caching changes
807 recompute_overlaying_specifier (Lisp_Object real_one[4])
809 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
810 Fset_specifier_dirty_flag (real_one[pos]);
814 gutter_specs_changed (Lisp_Object specifier, struct window *w,
815 Lisp_Object oldval, enum gutter_pos pos)
817 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
818 w->real_gutter_size[pos] = w->gutter_size[pos];
820 if (EQ (w->real_gutter_size[pos], Qautodetect)
821 && !NILP (w->gutter_visible_p[pos]))
823 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
826 MARK_MODELINE_CHANGED;
827 MARK_WINDOWS_CHANGED (w);
830 /* We define all of these so we can access which actual gutter changed. */
832 top_gutter_specs_changed (Lisp_Object specifier, struct window *w,
835 gutter_specs_changed (specifier, w, oldval, TOP_GUTTER);
839 bottom_gutter_specs_changed (Lisp_Object specifier, struct window *w,
842 gutter_specs_changed (specifier, w, oldval, BOTTOM_GUTTER);
846 left_gutter_specs_changed (Lisp_Object specifier, struct window *w,
849 gutter_specs_changed (specifier, w, oldval, LEFT_GUTTER);
853 right_gutter_specs_changed (Lisp_Object specifier, struct window *w,
856 gutter_specs_changed (specifier, w, oldval, RIGHT_GUTTER);
860 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
863 recompute_overlaying_specifier (Vgutter);
867 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
871 GUTTER_POS_LOOP (pos)
873 w->real_gutter_size[pos] = w->gutter_size[pos];
874 if (EQ (w->real_gutter_size[pos], Qautodetect)
875 && !NILP (w->gutter_visible_p[pos]))
877 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
882 MARK_MODELINE_CHANGED;
883 MARK_WINDOWS_CHANGED (w);
887 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
890 recompute_overlaying_specifier (Vgutter_size);
894 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
898 recompute_overlaying_specifier (Vgutter_border_width);
902 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
906 recompute_overlaying_specifier (Vgutter_visible_p);
907 /* Need to reconstruct the gutter specifier as it is affected by the
909 recompute_overlaying_specifier (Vgutter);
913 DECLARE_SPECIFIER_TYPE (gutter_size);
914 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
915 DEFINE_SPECIFIER_TYPE (gutter_size);
918 gutter_size_validate (Lisp_Object instantiator)
920 if (NILP (instantiator))
923 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
924 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
927 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
928 Return non-nil if OBJECT is a gutter-size specifier.
930 See `make-gutter-size-specifier' for a description of possible gutter-size
935 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
938 DECLARE_SPECIFIER_TYPE (gutter_visible);
939 #define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible)
940 DEFINE_SPECIFIER_TYPE (gutter_visible);
943 gutter_visible_validate (Lisp_Object instantiator)
945 if (NILP (instantiator))
948 if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator))
949 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
952 if (CONSP (instantiator))
956 EXTERNAL_LIST_LOOP (rest, instantiator)
958 if (!SYMBOLP (XCAR (rest)))
959 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
965 DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /*
966 Return non-nil if OBJECT is a gutter-visible specifier.
968 See `make-gutter-visible-specifier' for a description of possible
969 gutter-visible instantiators.
973 return GUTTER_VISIBLE_SPECIFIERP (object) ? Qt : Qnil;
976 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
977 Ensure that all gutters are correctly showing their gutter specifier.
981 Lisp_Object devcons, concons;
983 DEVICE_LOOP_NO_BREAK (devcons, concons)
985 struct device *d = XDEVICE (XCAR (devcons));
988 DEVICE_FRAME_LOOP (frmcons, d)
990 struct frame *f = XFRAME (XCAR (frmcons));
992 MAYBE_DEVMETH (d, frame_output_begin, (f));
994 /* Sequence is quite important here. We not only want to
995 redisplay the gutter area but we also want to flush any
996 frame size changes out so that the gutter redisplay happens
997 in a kosha environment.
999 This is not only so that things look right but so that
1000 glyph redisplay optimization kicks in, by default display
1001 lines will be completely re-output if
1002 f->windows_structure_changed is 1, and this is true if
1003 frame size changes haven't been flushed out. Once frame
1004 size changes have been flushed out we then need to
1005 redisplay the frame in order to flush out pending window
1007 update_frame_gutter_geometry (f);
1009 if (f->windows_structure_changed)
1010 redisplay_frame (f, 1);
1011 else if (FRAME_REPAINT_P (f))
1013 /* We have to be "in display" when we output the gutter
1015 hold_frame_size_changes ();
1016 update_frame_gutters (f);
1017 unhold_one_frame_size_changes (f);
1020 MAYBE_DEVMETH (d, frame_output_end, (f));
1023 d->gutter_changed = 0;
1026 /* This is so that further changes to the gutters will trigger redisplay. */
1027 gutter_changed_set = 0;
1034 init_frame_gutters (struct frame *f)
1036 enum gutter_pos pos;
1037 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
1038 /* We are here as far in frame creation so cached specifiers are
1039 already recomputed, and possibly modified by resource
1040 initialization. We need to recalculate autodetected gutters. */
1041 GUTTER_POS_LOOP (pos)
1043 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
1044 w->real_gutter_size[pos] = w->gutter_size[pos];
1045 if (EQ (w->gutter_size[pos], Qautodetect)
1046 && !NILP (w->gutter_visible_p[pos]))
1048 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
1049 MARK_GUTTER_CHANGED;
1050 MARK_WINDOWS_CHANGED (w);
1054 /* Keep a record of the current sizes of things. */
1055 GUTTER_POS_LOOP (pos)
1057 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
1062 syms_of_gutter (void)
1064 DEFSUBR (Fgutter_specifier_p);
1065 DEFSUBR (Fgutter_size_specifier_p);
1066 DEFSUBR (Fgutter_visible_specifier_p);
1067 DEFSUBR (Fset_default_gutter_position);
1068 DEFSUBR (Fdefault_gutter_position);
1069 DEFSUBR (Fgutter_pixel_height);
1070 DEFSUBR (Fgutter_pixel_width);
1071 DEFSUBR (Fredisplay_gutter_area);
1073 defsymbol (&Qgutter_size, "gutter-size");
1074 defsymbol (&Qgutter_visible, "gutter-visible");
1075 defsymbol (&Qdefault_gutter_position_changed_hook,
1076 "default-gutter-position-changed-hook");
1080 vars_of_gutter (void)
1082 staticpro (&Vdefault_gutter_position);
1083 Vdefault_gutter_position = Qtop;
1089 specifier_type_create_gutter (void)
1091 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
1092 SPECIFIER_HAS_METHOD (gutter, validate);
1093 SPECIFIER_HAS_METHOD (gutter, after_change);
1095 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
1096 SPECIFIER_HAS_METHOD (gutter_size, validate);
1098 INITIALIZE_SPECIFIER_TYPE (gutter_visible, "gutter-visible", "gutter-visible-specifier-p");
1099 SPECIFIER_HAS_METHOD (gutter_visible, validate);
1103 reinit_specifier_type_create_gutter (void)
1105 REINITIALIZE_SPECIFIER_TYPE (gutter);
1106 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
1107 REINITIALIZE_SPECIFIER_TYPE (gutter_visible);
1111 specifier_vars_of_gutter (void)
1115 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
1116 Specifier for a fallback gutter.
1117 Use `set-specifier' to change this.
1119 The position of this gutter is specified in the function
1120 `default-gutter-position'. If the corresponding position-specific
1121 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
1122 does not specify a gutter in a particular domain (usually a window),
1123 then the value of `default-gutter' in that domain, if any, will be
1126 Note that the gutter at any particular position will not be
1127 displayed unless its visibility flag is true and its thickness
1128 \(width or height, depending on orientation) is non-zero. The
1129 visibility is controlled by the specifiers `top-gutter-visible-p',
1130 `bottom-gutter-visible-p', `left-gutter-visible-p', and
1131 `right-gutter-visible-p', and the thickness is controlled by the
1132 specifiers `top-gutter-height', `bottom-gutter-height',
1133 `left-gutter-width', and `right-gutter-width'.
1135 Note that one of the four visibility specifiers inherits from
1136 `default-gutter-visibility' and one of the four thickness
1137 specifiers inherits from either `default-gutter-width' or
1138 `default-gutter-height' (depending on orientation), just
1139 like for the gutter description specifiers (e.g. `top-gutter')
1142 Therefore, if you are setting `default-gutter', you should control
1143 the visibility and thickness using `default-gutter-visible-p',
1144 `default-gutter-width', and `default-gutter-height', rather than
1145 using position-specific specifiers. That way, you will get sane
1146 behavior if the user changes the default gutter position.
1148 The gutter value should be a string, a property list of strings or
1149 nil. You can attach extents and glyphs to the string and hence display
1150 glyphs and text in other fonts in the gutter area. If the gutter value
1151 is a property list then the strings will be concatenated together
1152 before being displayed. */ );
1154 Vdefault_gutter = Fmake_specifier (Qgutter);
1155 /* #### It would be even nicer if the specifier caching
1156 automatically knew about specifier fallbacks, so we didn't
1157 have to do it ourselves. */
1158 set_specifier_caching (Vdefault_gutter,
1159 offsetof (struct window, default_gutter),
1160 default_gutter_specs_changed,
1163 DEFVAR_SPECIFIER ("top-gutter",
1164 &Vgutter[TOP_GUTTER] /*
1165 Specifier for the gutter at the top of the frame.
1166 Use `set-specifier' to change this.
1167 See `default-gutter' for a description of a valid gutter instantiator.
1169 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
1170 set_specifier_caching (Vgutter[TOP_GUTTER],
1171 offsetof (struct window, gutter[TOP_GUTTER]),
1172 top_gutter_specs_changed,
1175 DEFVAR_SPECIFIER ("bottom-gutter",
1176 &Vgutter[BOTTOM_GUTTER] /*
1177 Specifier for the gutter at the bottom of the frame.
1178 Use `set-specifier' to change this.
1179 See `default-gutter' for a description of a valid gutter instantiator.
1181 Note that, unless the `default-gutter-position' is `bottom', by
1182 default the height of the bottom gutter (controlled by
1183 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
1184 displayed even if you provide a value for `bottom-gutter'.
1186 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
1187 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
1188 offsetof (struct window, gutter[BOTTOM_GUTTER]),
1189 bottom_gutter_specs_changed,
1192 DEFVAR_SPECIFIER ("left-gutter",
1193 &Vgutter[LEFT_GUTTER] /*
1194 Specifier for the gutter at the left edge of the frame.
1195 Use `set-specifier' to change this.
1196 See `default-gutter' for a description of a valid gutter instantiator.
1198 Note that, unless the `default-gutter-position' is `left', by
1199 default the height of the left gutter (controlled by
1200 `left-gutter-width') is 0; thus, a left gutter will not be
1201 displayed even if you provide a value for `left-gutter'.
1203 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
1204 set_specifier_caching (Vgutter[LEFT_GUTTER],
1205 offsetof (struct window, gutter[LEFT_GUTTER]),
1206 left_gutter_specs_changed,
1209 DEFVAR_SPECIFIER ("right-gutter",
1210 &Vgutter[RIGHT_GUTTER] /*
1211 Specifier for the gutter at the right edge of the frame.
1212 Use `set-specifier' to change this.
1213 See `default-gutter' for a description of a valid gutter instantiator.
1215 Note that, unless the `default-gutter-position' is `right', by
1216 default the height of the right gutter (controlled by
1217 `right-gutter-width') is 0; thus, a right gutter will not be
1218 displayed even if you provide a value for `right-gutter'.
1220 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
1221 set_specifier_caching (Vgutter[RIGHT_GUTTER],
1222 offsetof (struct window, gutter[RIGHT_GUTTER]),
1223 right_gutter_specs_changed,
1226 /* initially, top inherits from default; this can be
1227 changed with `set-default-gutter-position'. */
1228 fb = list1 (Fcons (Qnil, Qnil));
1229 set_specifier_fallback (Vdefault_gutter, fb);
1230 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
1231 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
1232 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
1233 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
1235 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
1236 *Height of the default gutter, if it's oriented horizontally.
1237 This is a specifier; use `set-specifier' to change it.
1239 The position of the default gutter is specified by the function
1240 `set-default-gutter-position'. If the corresponding position-specific
1241 gutter thickness specifier (e.g. `top-gutter-height' if
1242 `default-gutter-position' is 'top) does not specify a thickness in a
1243 particular domain (a window or a frame), then the value of
1244 `default-gutter-height' or `default-gutter-width' (depending on the
1245 gutter orientation) in that domain, if any, will be used instead.
1247 Note that `default-gutter-height' is only used when
1248 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
1249 is only used when `default-gutter-position' is 'left or 'right.
1251 Note that all of the position-specific gutter thickness specifiers
1252 have a fallback value of zero when they do not correspond to the
1253 default gutter. Therefore, you will have to set a non-zero thickness
1254 value if you want a position-specific gutter to be displayed.
1256 If you set the height to 'autodetect the size of the gutter will be
1257 calculated to be large enough to hold the contents of the gutter. This
1260 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
1261 set_specifier_caching (Vdefault_gutter_height,
1262 offsetof (struct window, default_gutter_height),
1263 default_gutter_size_changed_in_window,
1266 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
1267 *Width of the default gutter, if it's oriented vertically.
1268 This is a specifier; use `set-specifier' to change it.
1270 See `default-gutter-height' for more information.
1272 Vdefault_gutter_width = Fmake_specifier (Qnatnum);
1273 set_specifier_caching (Vdefault_gutter_width,
1274 offsetof (struct window, default_gutter_width),
1275 default_gutter_size_changed_in_window,
1278 DEFVAR_SPECIFIER ("top-gutter-height",
1279 &Vgutter_size[TOP_GUTTER] /*
1280 *Height of the top gutter.
1281 This is a specifier; use `set-specifier' to change it.
1283 See `default-gutter-height' for more information.
1285 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
1286 set_specifier_caching (Vgutter_size[TOP_GUTTER],
1287 offsetof (struct window, gutter_size[TOP_GUTTER]),
1288 gutter_geometry_changed_in_window, 0, 0);
1290 DEFVAR_SPECIFIER ("bottom-gutter-height",
1291 &Vgutter_size[BOTTOM_GUTTER] /*
1292 *Height of the bottom gutter.
1293 This is a specifier; use `set-specifier' to change it.
1295 See `default-gutter-height' for more information.
1297 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
1298 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
1299 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
1300 gutter_geometry_changed_in_window, 0, 0);
1302 DEFVAR_SPECIFIER ("left-gutter-width",
1303 &Vgutter_size[LEFT_GUTTER] /*
1304 *Width of left gutter.
1305 This is a specifier; use `set-specifier' to change it.
1307 See `default-gutter-height' for more information.
1309 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1310 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
1311 offsetof (struct window, gutter_size[LEFT_GUTTER]),
1312 gutter_geometry_changed_in_window, 0, 0);
1314 DEFVAR_SPECIFIER ("right-gutter-width",
1315 &Vgutter_size[RIGHT_GUTTER] /*
1316 *Width of right gutter.
1317 This is a specifier; use `set-specifier' to change it.
1319 See `default-gutter-height' for more information.
1321 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1322 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
1323 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
1324 gutter_geometry_changed_in_window, 0, 0);
1328 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1330 #ifdef HAVE_X_WINDOWS
1331 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
1333 #ifdef HAVE_MS_WINDOWS
1334 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
1335 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1338 set_specifier_fallback (Vdefault_gutter_height, fb);
1342 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1344 #ifdef HAVE_X_WINDOWS
1345 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb);
1347 #ifdef HAVE_MS_WINDOWS
1348 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1349 fb = Fcons (Fcons (list1 (Qmswindows),
1350 make_int (DEFAULT_GUTTER_WIDTH)), fb);
1353 set_specifier_fallback (Vdefault_gutter_width, fb);
1355 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1356 fb = list1 (Fcons (Qnil, Qzero));
1357 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1358 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1359 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1361 DEFVAR_SPECIFIER ("default-gutter-border-width",
1362 &Vdefault_gutter_border_width /*
1363 *Width of the border around the default gutter.
1364 This is a specifier; use `set-specifier' to change it.
1366 The position of the default gutter is specified by the function
1367 `set-default-gutter-position'. If the corresponding position-specific
1368 gutter border width specifier (e.g. `top-gutter-border-width' if
1369 `default-gutter-position' is 'top) does not specify a border width in a
1370 particular domain (a window or a frame), then the value of
1371 `default-gutter-border-width' in that domain, if any, will be used
1375 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1376 set_specifier_caching (Vdefault_gutter_border_width,
1377 offsetof (struct window, default_gutter_border_width),
1378 default_gutter_border_width_changed_in_window,
1381 DEFVAR_SPECIFIER ("top-gutter-border-width",
1382 &Vgutter_border_width[TOP_GUTTER] /*
1383 *Border width of the top gutter.
1384 This is a specifier; use `set-specifier' to change it.
1386 See `default-gutter-height' for more information.
1388 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1389 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1390 offsetof (struct window,
1391 gutter_border_width[TOP_GUTTER]),
1392 gutter_geometry_changed_in_window, 0, 0);
1394 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1395 &Vgutter_border_width[BOTTOM_GUTTER] /*
1396 *Border width of the bottom gutter.
1397 This is a specifier; use `set-specifier' to change it.
1399 See `default-gutter-height' for more information.
1401 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1402 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1403 offsetof (struct window,
1404 gutter_border_width[BOTTOM_GUTTER]),
1405 gutter_geometry_changed_in_window, 0, 0);
1407 DEFVAR_SPECIFIER ("left-gutter-border-width",
1408 &Vgutter_border_width[LEFT_GUTTER] /*
1409 *Border width of left gutter.
1410 This is a specifier; use `set-specifier' to change it.
1412 See `default-gutter-height' for more information.
1414 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1415 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1416 offsetof (struct window,
1417 gutter_border_width[LEFT_GUTTER]),
1418 gutter_geometry_changed_in_window, 0, 0);
1420 DEFVAR_SPECIFIER ("right-gutter-border-width",
1421 &Vgutter_border_width[RIGHT_GUTTER] /*
1422 *Border width of right gutter.
1423 This is a specifier; use `set-specifier' to change it.
1425 See `default-gutter-height' for more information.
1427 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1428 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1429 offsetof (struct window,
1430 gutter_border_width[RIGHT_GUTTER]),
1431 gutter_geometry_changed_in_window, 0, 0);
1435 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1437 #ifdef HAVE_X_WINDOWS
1438 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1440 #ifdef HAVE_MS_WINDOWS
1441 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1442 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1445 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1447 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1448 fb = list1 (Fcons (Qnil, Qzero));
1449 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1450 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1451 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1453 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1454 *Whether the default gutter is visible.
1455 This is a specifier; use `set-specifier' to change it.
1457 The position of the default gutter is specified by the function
1458 `set-default-gutter-position'. If the corresponding position-specific
1459 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1460 `default-gutter-position' is 'top) does not specify a visible-p value
1461 in a particular domain (a window or a frame), then the value of
1462 `default-gutter-visible-p' in that domain, if any, will be used
1465 `default-gutter-visible-p' and all of the position-specific gutter
1466 visibility specifiers have a fallback value of true.
1468 Vdefault_gutter_visible_p = Fmake_specifier (Qgutter_visible);
1469 set_specifier_caching (Vdefault_gutter_visible_p,
1470 offsetof (struct window,
1471 default_gutter_visible_p),
1472 default_gutter_visible_p_changed_in_window,
1475 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1476 &Vgutter_visible_p[TOP_GUTTER] /*
1477 *Whether the top gutter is visible.
1478 This is a specifier; use `set-specifier' to change it.
1480 See `default-gutter-visible-p' for more information.
1482 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qgutter_visible);
1483 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1484 offsetof (struct window,
1485 gutter_visible_p[TOP_GUTTER]),
1486 top_gutter_specs_changed, 0, 0);
1488 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1489 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1490 *Whether the bottom gutter is visible.
1491 This is a specifier; use `set-specifier' to change it.
1493 See `default-gutter-visible-p' for more information.
1495 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_visible);
1496 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1497 offsetof (struct window,
1498 gutter_visible_p[BOTTOM_GUTTER]),
1499 bottom_gutter_specs_changed, 0, 0);
1501 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1502 &Vgutter_visible_p[LEFT_GUTTER] /*
1503 *Whether the left gutter is visible.
1504 This is a specifier; use `set-specifier' to change it.
1506 See `default-gutter-visible-p' for more information.
1508 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qgutter_visible);
1509 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1510 offsetof (struct window,
1511 gutter_visible_p[LEFT_GUTTER]),
1512 left_gutter_specs_changed, 0, 0);
1514 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1515 &Vgutter_visible_p[RIGHT_GUTTER] /*
1516 *Whether the right gutter is visible.
1517 This is a specifier; use `set-specifier' to change it.
1519 See `default-gutter-visible-p' for more information.
1521 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qgutter_visible);
1522 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1523 offsetof (struct window,
1524 gutter_visible_p[RIGHT_GUTTER]),
1525 right_gutter_specs_changed, 0, 0);
1527 /* initially, top inherits from default; this can be
1528 changed with `set-default-gutter-position'. */
1529 fb = list1 (Fcons (Qnil, Qt));
1530 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1531 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1532 Vdefault_gutter_visible_p);
1533 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1534 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1535 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);