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));
222 display_boxes_in_gutter_p
224 Determine whether the required display_glyph_area is completely
225 inside the gutter. -1 means the display_box is not in the gutter. 1
226 means the display_box and the display_glyph_area are in the
227 window. 0 means the display_box is in the gutter but the
228 display_glyph_area is not. */
229 int display_boxes_in_gutter_p (struct frame *f, struct display_box* db,
230 struct display_glyph_area* dga)
233 GUTTER_POS_LOOP (pos)
235 if (FRAME_GUTTER_VISIBLE (f, pos))
237 int x, y, width, height;
238 get_gutter_coords (f, pos, &x, &y, &width, &height);
239 if (db->xpos + dga->xoffset >= x
241 db->ypos + dga->yoffset >= y
243 db->xpos + dga->xoffset + dga->width <= x + width
245 db->ypos + dga->yoffset + dga->height <= y + height)
247 else if (db->xpos >= x && db->ypos >= y
248 && db->xpos + db->width <= x + width
249 && db->ypos + db->height <= y + height)
256 /* Convert the gutter specifier into something we can actually
258 static Lisp_Object construct_window_gutter_spec (struct window* w,
261 Lisp_Object rest, *args;
263 Lisp_Object gutter = RAW_WINDOW_GUTTER (w, pos);
265 if (STRINGP (gutter) || NILP (gutter))
268 GET_LIST_LENGTH (gutter, nargs);
269 args = alloca_array (Lisp_Object, nargs >> 1);
272 for (rest = gutter; !NILP (rest); rest = XCDR (XCDR (rest)))
274 /* We only put things in the real gutter that are declared to be
276 if (!CONSP (WINDOW_GUTTER_VISIBLE (w, pos))
278 !NILP (Fmemq (XCAR (rest), WINDOW_GUTTER_VISIBLE (w, pos))))
280 args [nargs++] = XCAR (XCDR (rest));
284 return Fconcat (nargs, args);
287 /* Sizing gutters is a pain so we try and help the user by determining
288 what height will accommodate all lines. This is useless on left and
289 right gutters as we always have a maximal number of lines. */
291 calculate_gutter_size_from_display_lines (enum gutter_pos pos,
292 display_line_dynarr* ddla)
295 struct display_line *dl;
297 /* For top and bottom the calculation is easy. */
298 if (pos == TOP_GUTTER || pos == BOTTOM_GUTTER)
300 /* grab coordinates of last line */
301 if (Dynarr_length (ddla))
303 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
304 size = (dl->ypos + dl->descent - dl->clip)
305 - (Dynarr_atp (ddla, 0)->ypos - Dynarr_atp (ddla, 0)->ascent);
308 /* For left and right we have to do some maths. */
311 int start_pos = 0, end_pos = 0, line;
312 for (line = 0; line < Dynarr_length (ddla); line++)
315 dl = Dynarr_atp (ddla, line);
317 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
319 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
321 if (db->type == TEXT)
323 start_pos = min (db->start_pos, start_pos);
324 end_pos = max (db->end_pos, end_pos);
328 size = end_pos - start_pos;
335 calculate_gutter_size (struct window *w, enum gutter_pos pos)
337 struct frame* f = XFRAME (WINDOW_FRAME (w));
339 display_line_dynarr* ddla;
340 Lisp_Object ret = Qnil;
342 /* degenerate case */
343 if (NILP (RAW_WINDOW_GUTTER (w, pos))
350 /* Redisplay code that we use relies on GC not happening. Make it
352 count = specpdl_depth ();
353 record_unwind_protect (restore_gc_inhibit,
354 make_int (gc_currently_forbidden));
355 gc_currently_forbidden = 1;
357 ddla = Dynarr_new (display_line);
358 /* generate some display lines */
359 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
360 FRAME_LEFT_BORDER_END (f),
361 FRAME_TOP_BORDER_END (f),
362 FRAME_RIGHT_BORDER_START (f)
363 - FRAME_LEFT_BORDER_END (f),
364 FRAME_BOTTOM_BORDER_START (f)
365 - FRAME_TOP_BORDER_END (f),
368 /* Let GC happen again. */
369 unbind_to (count, Qnil);
371 ret = make_int (calculate_gutter_size_from_display_lines (pos, ddla));
372 free_display_lines (ddla);
378 output_gutter (struct frame *f, enum gutter_pos pos, int force)
381 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
382 struct device *d = XDEVICE (f->device);
383 struct window* w = XWINDOW (window);
384 int x, y, width, height, ypos;
385 int line, border_width;
387 display_line_dynarr* ddla, *cdla;
388 struct display_line *dl = 0;
391 if (!WINDOW_LIVE_P (w))
394 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
395 findex = get_builtin_face_cache_index (w, Vwidget_face);
397 if (!f->current_display_lines[pos])
398 f->current_display_lines[pos] = Dynarr_new (display_line);
399 if (!f->desired_display_lines[pos])
400 f->desired_display_lines[pos] = Dynarr_new (display_line);
402 ddla = f->desired_display_lines[pos];
403 cdla = f->current_display_lines[pos];
404 cdla_len = Dynarr_length (cdla);
406 XSETFRAME (frame, f);
408 get_gutter_coords (f, pos, &x, &y, &width, &height);
409 /* generate some display lines */
410 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
411 x + border_width, y + border_width,
412 width - 2 * border_width,
413 height - 2 * border_width, ddla, 0, findex);
415 /* We only output the gutter if we think something of significance
416 has changed. This is, for example, because redisplay can cause
417 new face cache elements to get added causing compare_runes to
418 fail because the findex for a particular face has changed. */
419 if (force || f->faces_changed || f->frame_changed ||
420 f->gutter_changed || f->glyphs_changed ||
421 f->size_changed || f->subwindows_changed ||
422 w->windows_changed || f->windows_structure_changed ||
423 cdla_len != Dynarr_length (ddla) ||
424 (f->extents_changed && w->gutter_extent_modiff[pos]))
427 printf ("gutter redisplay [%dx%d@%d+%d] triggered by %s,\n",
428 width, height, x, y, force ? "force" :
429 f->faces_changed ? "f->faces_changed" :
430 f->frame_changed ? "f->frame_changed" :
431 f->gutter_changed ? "f->gutter_changed" :
432 f->glyphs_changed ? "f->glyphs_changed" :
433 f->size_changed ? "f->size_changed" :
434 f->subwindows_changed ? "f->subwindows_changed" :
435 w->windows_changed ? "w->windows_changed" :
436 f->windows_structure_changed ? "f->windows_structure_changed" :
437 cdla_len != Dynarr_length (ddla) ? "different display structures" :
438 f->extents_changed && w->gutter_extent_modiff[pos] ?
439 "f->extents_changed && w->gutter_extent_modiff[pos]" : "<null>");
441 /* Output each line. */
442 for (line = 0; line < Dynarr_length (ddla); line++)
444 output_display_line (w, cdla, ddla, line, -1, -1);
447 /* If the number of display lines has shrunk, adjust. */
448 if (cdla_len > Dynarr_length (ddla))
450 Dynarr_length (cdla) = Dynarr_length (ddla);
453 /* grab coordinates of last line and blank after it. */
454 if (Dynarr_length (ddla) > 0)
456 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
457 ypos = dl->ypos + dl->descent - dl->clip;
462 redisplay_clear_region (window, findex, x + border_width , ypos,
463 width - 2 * border_width, height - (ypos - y) - border_width);
464 /* If, for some reason, we have more to display than we have
465 room for, and we are allowed to resize the gutter, then make
466 sure this happens before the next time we try and
467 output. This can happen when face font sizes change. */
468 if (dl && EQ (w->gutter_size[pos], Qautodetect)
470 calculate_gutter_size_from_display_lines (pos, ddla) >
471 WINDOW_GUTTER_SIZE_INTERNAL (w, pos)))
473 /* #### Ideally we would just mark the specifier as dirty
474 and everything else would "just work". Unfortunately we have
475 two problems with this. One is that the specifier cache
476 won't be recalculated unless the specifier code thinks the
477 cached value has actually changed, even though we have
478 marked the specifier as dirty. Additionally, although doing
479 this results in a gutter size change, we never seem to get
480 back into redisplay so that the frame size can be updated. I
481 think this is because we are already in redisplay and later
482 on the frame will be marked as clean. Thus we also have to
483 force a pending recalculation of the frame size. */
484 w->gutter_size[pos] = Qnil;
485 Fset_specifier_dirty_flag (Vgutter_size[pos]);
486 update_gutter_geometry (f, pos);
489 /* bevel the gutter area if so desired */
490 if (border_width != 0)
492 MAYBE_DEVMETH (d, bevel_area,
493 (w, findex, x, y, width, height, border_width,
494 EDGE_ALL, EDGE_BEVEL_OUT));
499 /* Nothing of significance happened so sync the display line
501 for (line = 0; line < Dynarr_length (ddla); line++)
503 sync_display_line_structs (w, line, 1, cdla, ddla);
507 w->gutter_extent_modiff [pos] = 0;
511 clear_gutter (struct frame *f, enum gutter_pos pos)
513 int x, y, width, height;
514 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
515 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
517 get_gutter_coords (f, pos, &x, &y, &width, &height);
519 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
521 redisplay_clear_region (window, findex, x, y, width, height);
524 /* #### I don't currently believe that redisplay needs to mark the
525 glyphs in its structures since these will always be referenced from
526 somewhere else. However, I'm not sure enough to stake my life on it
527 at this point, so we do the safe thing. */
529 /* See the comment in image_instantiate_cache_result as to why marking
530 the glyph will also mark the image_instance. */
532 mark_gutters (struct frame* f)
535 GUTTER_POS_LOOP (pos)
537 if (f->current_display_lines[pos])
538 mark_redisplay_structs (f->current_display_lines[pos]);
539 /* #### Do we really need to mark the desired lines? */
540 if (f->desired_display_lines[pos])
541 mark_redisplay_structs (f->desired_display_lines[pos]);
545 /* This is called by extent_changed_for_redisplay, so that redisplay
546 knows exactly what extents have changed. */
548 gutter_extent_signal_changed_region_maybe (Lisp_Object obj,
549 Bufpos start, Bufpos end)
551 /* #### Start and end are currently ignored but could be used by a
552 more optimal gutter redisplay. We currently loop over all frames
553 here, this could be optimized. */
554 Lisp_Object frmcons, devcons, concons;
556 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
558 struct frame *f = XFRAME (XCAR (frmcons));
560 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
561 struct window* w = XWINDOW (window);
563 GUTTER_POS_LOOP (pos)
565 if (EQ (WINDOW_GUTTER (w, pos), obj))
567 w->gutter_extent_modiff[pos]++;
573 /* We have to change the gutter geometry separately to the gutter
574 update since it needs to occur outside of redisplay proper. */
576 update_gutter_geometry (struct frame *f, enum gutter_pos pos)
578 /* If the gutter geometry has changed then re-layout the
579 frame. If we are in display there is almost no point in doing
580 anything else since the frame size changes will be delayed
581 until we are out of redisplay proper. */
582 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos])
585 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
587 change_frame_size (f, height, width, 0);
588 MARK_FRAME_LAYOUT_CHANGED (f);
591 /* Mark sizes as up-to-date. */
592 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
596 update_frame_gutter_geometry (struct frame *f)
598 if (f->gutter_changed
599 || f->frame_layout_changed
600 || f->windows_structure_changed)
604 /* If the gutter geometry has changed then re-layout the
605 frame. If we are in display there is almost no point in doing
606 anything else since the frame size changes will be delayed
607 until we are out of redisplay proper. */
608 GUTTER_POS_LOOP (pos)
610 update_gutter_geometry (f, pos);
616 update_frame_gutters (struct frame *f)
618 if (f->faces_changed || f->frame_changed ||
619 f->gutter_changed || f->glyphs_changed ||
620 f->size_changed || f->subwindows_changed ||
621 f->windows_changed || f->windows_structure_changed ||
622 f->extents_changed || f->frame_layout_changed)
626 /* We don't actually care about these when outputting the gutter
627 so locally disable them. */
628 int local_clip_changed = f->clip_changed;
629 int local_buffers_changed = f->buffers_changed;
631 f->buffers_changed = 0;
634 GUTTER_POS_LOOP (pos)
636 if (FRAME_GUTTER_VISIBLE (f, pos))
637 output_gutter (f, pos, 0);
639 else if (gutter_was_visible (f, pos))
640 clear_gutter (f, pos);
643 f->clip_changed = local_clip_changed;
644 f->buffers_changed = local_buffers_changed;
645 f->gutter_changed = 0;
650 reset_gutter_display_lines (struct frame* f)
653 GUTTER_POS_LOOP (pos)
655 if (f->current_display_lines[pos])
656 Dynarr_reset (f->current_display_lines[pos]);
661 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
662 int width, int height)
664 int g_x, g_y, g_width, g_height;
666 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
668 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
670 if (((x + width) < g_x) || (x > (g_x + g_width)))
674 printf ("redrawing gutter after expose %d+%d, %dx%d\n",
675 x, y, width, height);
677 /* #### optimize this - redrawing the whole gutter for every expose
678 is very expensive. We reset the current display lines because if
679 they're being exposed they are no longer current. */
680 reset_gutter_display_lines (f);
682 /* Even if none of the gutter is in the area, the blank region at
683 the very least must be because the first thing we did is verify
684 that some portion of the gutter is in the exposed region. */
685 output_gutter (f, pos, 1);
689 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
694 /* We have to be "in display" when we output the gutter - make it
696 hold_frame_size_changes ();
697 GUTTER_POS_LOOP (pos)
699 if (FRAME_GUTTER_VISIBLE (f, pos))
700 redraw_exposed_gutter (f, pos, x, y, width, height);
702 unhold_one_frame_size_changes (f);
706 free_frame_gutters (struct frame *f)
709 GUTTER_POS_LOOP (pos)
711 if (f->current_display_lines[pos])
713 free_display_lines (f->current_display_lines[pos]);
714 f->current_display_lines[pos] = 0;
716 if (f->desired_display_lines[pos])
718 free_display_lines (f->desired_display_lines[pos]);
719 f->desired_display_lines[pos] = 0;
724 static enum gutter_pos
725 decode_gutter_position (Lisp_Object position)
727 if (EQ (position, Qtop)) return TOP_GUTTER;
728 if (EQ (position, Qbottom)) return BOTTOM_GUTTER;
729 if (EQ (position, Qleft)) return LEFT_GUTTER;
730 if (EQ (position, Qright)) return RIGHT_GUTTER;
731 signal_simple_error ("Invalid gutter position", position);
733 return TOP_GUTTER; /* not reached */
736 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /*
737 Set the position that the `default-gutter' will be displayed at.
738 Valid positions are 'top, 'bottom, 'left and 'right.
739 See `default-gutter-position'.
743 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position);
744 enum gutter_pos new = decode_gutter_position (position);
748 /* The following calls will automatically cause the dirty
749 flags to be set; we delay frame size changes to avoid
750 lots of frame flickering. */
751 /* #### I think this should be GC protected. -sb */
752 hold_frame_size_changes ();
753 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil)));
754 set_specifier_fallback (Vgutter[new], Vdefault_gutter);
755 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero)));
756 set_specifier_fallback (Vgutter_size[new],
757 new == TOP_GUTTER || new == BOTTOM_GUTTER
758 ? Vdefault_gutter_height
759 : Vdefault_gutter_width);
760 set_specifier_fallback (Vgutter_border_width[cur],
761 list1 (Fcons (Qnil, Qzero)));
762 set_specifier_fallback (Vgutter_border_width[new],
763 Vdefault_gutter_border_width);
764 set_specifier_fallback (Vgutter_visible_p[cur], list1 (Fcons (Qnil, Qt)));
765 set_specifier_fallback (Vgutter_visible_p[new], Vdefault_gutter_visible_p);
767 Vdefault_gutter_position = position;
768 unhold_frame_size_changes ();
771 run_hook (Qdefault_gutter_position_changed_hook);
776 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
777 Return the position that the `default-gutter' will be displayed at.
778 The `default-gutter' will only be displayed here if the corresponding
779 position-specific gutter specifier does not provide a value.
783 return Vdefault_gutter_position;
786 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /*
787 Return the pixel width of the gutter at POS in LOCALE.
788 POS defaults to the default gutter position. LOCALE defaults to
793 int x, y, width, height;
794 enum gutter_pos p = TOP_GUTTER;
795 struct frame *f = decode_frame (FW_FRAME (locale));
798 pos = Vdefault_gutter_position;
799 p = decode_gutter_position (pos);
801 get_gutter_coords (f, p, &x, &y, &width, &height);
802 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
804 return make_int (width);
807 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /*
808 Return the pixel height of the gutter at POS in LOCALE.
809 POS defaults to the default gutter position. LOCALE defaults to
814 int x, y, width, height;
815 enum gutter_pos p = TOP_GUTTER;
816 struct frame *f = decode_frame (FW_FRAME (locale));
819 pos = Vdefault_gutter_position;
820 p = decode_gutter_position (pos);
822 get_gutter_coords (f, p, &x, &y, &width, &height);
823 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2);
825 return make_int (height);
828 DEFINE_SPECIFIER_TYPE (gutter);
831 gutter_after_change (Lisp_Object specifier, Lisp_Object locale)
837 gutter_validate (Lisp_Object instantiator)
839 if (NILP (instantiator))
842 /* Must be a string or a plist. */
843 if (!STRINGP (instantiator) && NILP (Fvalid_plist_p (instantiator)))
844 signal_simple_error ("Gutter spec must be string, plist or nil", instantiator);
846 if (!STRINGP (instantiator))
850 for (rest = instantiator; !NILP (rest); rest = XCDR (XCDR (rest)))
852 if (!SYMBOLP (XCAR (rest))
853 || !STRINGP (XCAR (XCDR (rest))))
854 signal_simple_error ("Gutter plist spec must contain strings", instantiator);
859 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
860 Return non-nil if OBJECT is a gutter specifier.
862 See `make-gutter-specifier' for a description of possible gutter
867 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
872 Helper for invalidating the real specifier when default
873 specifier caching changes
876 recompute_overlaying_specifier (Lisp_Object real_one[4])
878 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position);
879 Fset_specifier_dirty_flag (real_one[pos]);
883 gutter_specs_changed (Lisp_Object specifier, struct window *w,
884 Lisp_Object oldval, enum gutter_pos pos)
886 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
887 w->real_gutter_size[pos] = w->gutter_size[pos];
889 if (EQ (w->real_gutter_size[pos], Qautodetect)
890 && !NILP (w->gutter_visible_p[pos]))
892 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
895 MARK_MODELINE_CHANGED;
896 MARK_WINDOWS_CHANGED (w);
899 /* We define all of these so we can access which actual gutter changed. */
901 top_gutter_specs_changed (Lisp_Object specifier, struct window *w,
904 gutter_specs_changed (specifier, w, oldval, TOP_GUTTER);
908 bottom_gutter_specs_changed (Lisp_Object specifier, struct window *w,
911 gutter_specs_changed (specifier, w, oldval, BOTTOM_GUTTER);
915 left_gutter_specs_changed (Lisp_Object specifier, struct window *w,
918 gutter_specs_changed (specifier, w, oldval, LEFT_GUTTER);
922 right_gutter_specs_changed (Lisp_Object specifier, struct window *w,
925 gutter_specs_changed (specifier, w, oldval, RIGHT_GUTTER);
929 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
932 recompute_overlaying_specifier (Vgutter);
936 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
940 GUTTER_POS_LOOP (pos)
942 w->real_gutter_size[pos] = w->gutter_size[pos];
943 if (EQ (w->real_gutter_size[pos], Qautodetect)
944 && !NILP (w->gutter_visible_p[pos]))
946 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
951 MARK_MODELINE_CHANGED;
952 MARK_WINDOWS_CHANGED (w);
956 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
959 recompute_overlaying_specifier (Vgutter_size);
963 default_gutter_border_width_changed_in_window (Lisp_Object specifier,
967 recompute_overlaying_specifier (Vgutter_border_width);
971 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
975 recompute_overlaying_specifier (Vgutter_visible_p);
976 /* Need to reconstruct the gutter specifier as it is affected by the
978 recompute_overlaying_specifier (Vgutter);
982 DECLARE_SPECIFIER_TYPE (gutter_size);
983 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
984 DEFINE_SPECIFIER_TYPE (gutter_size);
987 gutter_size_validate (Lisp_Object instantiator)
989 if (NILP (instantiator))
992 if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
993 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
996 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
997 Return non-nil if OBJECT is a gutter-size specifier.
999 See `make-gutter-size-specifier' for a description of possible gutter-size
1004 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
1007 DECLARE_SPECIFIER_TYPE (gutter_visible);
1008 #define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible)
1009 DEFINE_SPECIFIER_TYPE (gutter_visible);
1012 gutter_visible_validate (Lisp_Object instantiator)
1014 if (NILP (instantiator))
1017 if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator))
1018 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
1021 if (CONSP (instantiator))
1025 EXTERNAL_LIST_LOOP (rest, instantiator)
1027 if (!SYMBOLP (XCAR (rest)))
1028 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
1034 DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /*
1035 Return non-nil if OBJECT is a gutter-visible specifier.
1037 See `make-gutter-visible-specifier' for a description of possible
1038 gutter-visible instantiators.
1042 return GUTTER_VISIBLE_SPECIFIERP (object) ? Qt : Qnil;
1045 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
1046 Ensure that all gutters are correctly showing their gutter specifier.
1050 Lisp_Object devcons, concons;
1052 DEVICE_LOOP_NO_BREAK (devcons, concons)
1054 struct device *d = XDEVICE (XCAR (devcons));
1055 Lisp_Object frmcons;
1057 DEVICE_FRAME_LOOP (frmcons, d)
1059 struct frame *f = XFRAME (XCAR (frmcons));
1061 MAYBE_DEVMETH (d, frame_output_begin, (f));
1063 /* Sequence is quite important here. We not only want to
1064 redisplay the gutter area but we also want to flush any
1065 frame size changes out so that the gutter redisplay happens
1066 in a kosha environment.
1068 This is not only so that things look right but so that
1069 glyph redisplay optimization kicks in, by default display
1070 lines will be completely re-output if
1071 f->windows_structure_changed is 1, and this is true if
1072 frame size changes haven't been flushed out. Once frame
1073 size changes have been flushed out we then need to
1074 redisplay the frame in order to flush out pending window
1076 update_frame_gutter_geometry (f);
1078 if (f->windows_structure_changed)
1079 redisplay_frame (f, 1);
1080 else if (FRAME_REPAINT_P (f))
1082 /* We have to be "in display" when we output the gutter
1084 hold_frame_size_changes ();
1085 update_frame_gutters (f);
1086 unhold_one_frame_size_changes (f);
1089 MAYBE_DEVMETH (d, frame_output_end, (f));
1092 d->gutter_changed = 0;
1095 /* This is so that further changes to the gutters will trigger redisplay. */
1096 gutter_changed_set = 0;
1103 init_frame_gutters (struct frame *f)
1105 enum gutter_pos pos;
1106 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
1107 /* We are here as far in frame creation so cached specifiers are
1108 already recomputed, and possibly modified by resource
1109 initialization. We need to recalculate autodetected gutters. */
1110 GUTTER_POS_LOOP (pos)
1112 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
1113 w->real_gutter_size[pos] = w->gutter_size[pos];
1114 if (EQ (w->gutter_size[pos], Qautodetect)
1115 && !NILP (w->gutter_visible_p[pos]))
1117 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
1118 MARK_GUTTER_CHANGED;
1119 MARK_WINDOWS_CHANGED (w);
1123 /* Keep a record of the current sizes of things. */
1124 GUTTER_POS_LOOP (pos)
1126 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
1131 syms_of_gutter (void)
1133 DEFSUBR (Fgutter_specifier_p);
1134 DEFSUBR (Fgutter_size_specifier_p);
1135 DEFSUBR (Fgutter_visible_specifier_p);
1136 DEFSUBR (Fset_default_gutter_position);
1137 DEFSUBR (Fdefault_gutter_position);
1138 DEFSUBR (Fgutter_pixel_height);
1139 DEFSUBR (Fgutter_pixel_width);
1140 DEFSUBR (Fredisplay_gutter_area);
1142 defsymbol (&Qgutter_size, "gutter-size");
1143 defsymbol (&Qgutter_visible, "gutter-visible");
1144 defsymbol (&Qdefault_gutter_position_changed_hook,
1145 "default-gutter-position-changed-hook");
1149 vars_of_gutter (void)
1151 staticpro (&Vdefault_gutter_position);
1152 Vdefault_gutter_position = Qtop;
1158 specifier_type_create_gutter (void)
1160 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
1161 SPECIFIER_HAS_METHOD (gutter, validate);
1162 SPECIFIER_HAS_METHOD (gutter, after_change);
1164 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
1165 SPECIFIER_HAS_METHOD (gutter_size, validate);
1167 INITIALIZE_SPECIFIER_TYPE (gutter_visible, "gutter-visible", "gutter-visible-specifier-p");
1168 SPECIFIER_HAS_METHOD (gutter_visible, validate);
1172 reinit_specifier_type_create_gutter (void)
1174 REINITIALIZE_SPECIFIER_TYPE (gutter);
1175 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
1176 REINITIALIZE_SPECIFIER_TYPE (gutter_visible);
1180 specifier_vars_of_gutter (void)
1184 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /*
1185 Specifier for a fallback gutter.
1186 Use `set-specifier' to change this.
1188 The position of this gutter is specified in the function
1189 `default-gutter-position'. If the corresponding position-specific
1190 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top)
1191 does not specify a gutter in a particular domain (usually a window),
1192 then the value of `default-gutter' in that domain, if any, will be
1195 Note that the gutter at any particular position will not be
1196 displayed unless its visibility flag is true and its thickness
1197 \(width or height, depending on orientation) is non-zero. The
1198 visibility is controlled by the specifiers `top-gutter-visible-p',
1199 `bottom-gutter-visible-p', `left-gutter-visible-p', and
1200 `right-gutter-visible-p', and the thickness is controlled by the
1201 specifiers `top-gutter-height', `bottom-gutter-height',
1202 `left-gutter-width', and `right-gutter-width'.
1204 Note that one of the four visibility specifiers inherits from
1205 `default-gutter-visibility' and one of the four thickness
1206 specifiers inherits from either `default-gutter-width' or
1207 `default-gutter-height' (depending on orientation), just
1208 like for the gutter description specifiers (e.g. `top-gutter')
1211 Therefore, if you are setting `default-gutter', you should control
1212 the visibility and thickness using `default-gutter-visible-p',
1213 `default-gutter-width', and `default-gutter-height', rather than
1214 using position-specific specifiers. That way, you will get sane
1215 behavior if the user changes the default gutter position.
1217 The gutter value should be a string, a property list of strings or
1218 nil. You can attach extents and glyphs to the string and hence display
1219 glyphs and text in other fonts in the gutter area. If the gutter value
1220 is a property list then the strings will be concatenated together
1221 before being displayed. */ );
1223 Vdefault_gutter = Fmake_specifier (Qgutter);
1224 /* #### It would be even nicer if the specifier caching
1225 automatically knew about specifier fallbacks, so we didn't
1226 have to do it ourselves. */
1227 set_specifier_caching (Vdefault_gutter,
1228 offsetof (struct window, default_gutter),
1229 default_gutter_specs_changed,
1232 DEFVAR_SPECIFIER ("top-gutter",
1233 &Vgutter[TOP_GUTTER] /*
1234 Specifier for the gutter at the top of the frame.
1235 Use `set-specifier' to change this.
1236 See `default-gutter' for a description of a valid gutter instantiator.
1238 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
1239 set_specifier_caching (Vgutter[TOP_GUTTER],
1240 offsetof (struct window, gutter[TOP_GUTTER]),
1241 top_gutter_specs_changed,
1244 DEFVAR_SPECIFIER ("bottom-gutter",
1245 &Vgutter[BOTTOM_GUTTER] /*
1246 Specifier for the gutter at the bottom of the frame.
1247 Use `set-specifier' to change this.
1248 See `default-gutter' for a description of a valid gutter instantiator.
1250 Note that, unless the `default-gutter-position' is `bottom', by
1251 default the height of the bottom gutter (controlled by
1252 `bottom-gutter-height') is 0; thus, a bottom gutter will not be
1253 displayed even if you provide a value for `bottom-gutter'.
1255 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
1256 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
1257 offsetof (struct window, gutter[BOTTOM_GUTTER]),
1258 bottom_gutter_specs_changed,
1261 DEFVAR_SPECIFIER ("left-gutter",
1262 &Vgutter[LEFT_GUTTER] /*
1263 Specifier for the gutter at the left edge of the frame.
1264 Use `set-specifier' to change this.
1265 See `default-gutter' for a description of a valid gutter instantiator.
1267 Note that, unless the `default-gutter-position' is `left', by
1268 default the height of the left gutter (controlled by
1269 `left-gutter-width') is 0; thus, a left gutter will not be
1270 displayed even if you provide a value for `left-gutter'.
1272 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
1273 set_specifier_caching (Vgutter[LEFT_GUTTER],
1274 offsetof (struct window, gutter[LEFT_GUTTER]),
1275 left_gutter_specs_changed,
1278 DEFVAR_SPECIFIER ("right-gutter",
1279 &Vgutter[RIGHT_GUTTER] /*
1280 Specifier for the gutter at the right edge of the frame.
1281 Use `set-specifier' to change this.
1282 See `default-gutter' for a description of a valid gutter instantiator.
1284 Note that, unless the `default-gutter-position' is `right', by
1285 default the height of the right gutter (controlled by
1286 `right-gutter-width') is 0; thus, a right gutter will not be
1287 displayed even if you provide a value for `right-gutter'.
1289 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
1290 set_specifier_caching (Vgutter[RIGHT_GUTTER],
1291 offsetof (struct window, gutter[RIGHT_GUTTER]),
1292 right_gutter_specs_changed,
1295 /* initially, top inherits from default; this can be
1296 changed with `set-default-gutter-position'. */
1297 fb = list1 (Fcons (Qnil, Qnil));
1298 set_specifier_fallback (Vdefault_gutter, fb);
1299 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter);
1300 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb);
1301 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb);
1302 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb);
1304 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /*
1305 *Height of the default gutter, if it's oriented horizontally.
1306 This is a specifier; use `set-specifier' to change it.
1308 The position of the default gutter is specified by the function
1309 `set-default-gutter-position'. If the corresponding position-specific
1310 gutter thickness specifier (e.g. `top-gutter-height' if
1311 `default-gutter-position' is 'top) does not specify a thickness in a
1312 particular domain (a window or a frame), then the value of
1313 `default-gutter-height' or `default-gutter-width' (depending on the
1314 gutter orientation) in that domain, if any, will be used instead.
1316 Note that `default-gutter-height' is only used when
1317 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width'
1318 is only used when `default-gutter-position' is 'left or 'right.
1320 Note that all of the position-specific gutter thickness specifiers
1321 have a fallback value of zero when they do not correspond to the
1322 default gutter. Therefore, you will have to set a non-zero thickness
1323 value if you want a position-specific gutter to be displayed.
1325 If you set the height to 'autodetect the size of the gutter will be
1326 calculated to be large enough to hold the contents of the gutter. This
1329 Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
1330 set_specifier_caching (Vdefault_gutter_height,
1331 offsetof (struct window, default_gutter_height),
1332 default_gutter_size_changed_in_window,
1335 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /*
1336 *Width of the default gutter, if it's oriented vertically.
1337 This is a specifier; use `set-specifier' to change it.
1339 See `default-gutter-height' for more information.
1341 Vdefault_gutter_width = Fmake_specifier (Qgutter_size);
1342 set_specifier_caching (Vdefault_gutter_width,
1343 offsetof (struct window, default_gutter_width),
1344 default_gutter_size_changed_in_window,
1347 DEFVAR_SPECIFIER ("top-gutter-height",
1348 &Vgutter_size[TOP_GUTTER] /*
1349 *Height of the top gutter.
1350 This is a specifier; use `set-specifier' to change it.
1352 See `default-gutter-height' for more information.
1354 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
1355 set_specifier_caching (Vgutter_size[TOP_GUTTER],
1356 offsetof (struct window, gutter_size[TOP_GUTTER]),
1357 gutter_geometry_changed_in_window, 0, 0, 1);
1359 DEFVAR_SPECIFIER ("bottom-gutter-height",
1360 &Vgutter_size[BOTTOM_GUTTER] /*
1361 *Height of the bottom gutter.
1362 This is a specifier; use `set-specifier' to change it.
1364 See `default-gutter-height' for more information.
1366 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
1367 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
1368 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
1369 gutter_geometry_changed_in_window, 0, 0, 1);
1371 DEFVAR_SPECIFIER ("left-gutter-width",
1372 &Vgutter_size[LEFT_GUTTER] /*
1373 *Width of left gutter.
1374 This is a specifier; use `set-specifier' to change it.
1376 See `default-gutter-height' for more information.
1378 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qgutter_size);
1379 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
1380 offsetof (struct window, gutter_size[LEFT_GUTTER]),
1381 gutter_geometry_changed_in_window, 0, 0, 1);
1383 DEFVAR_SPECIFIER ("right-gutter-width",
1384 &Vgutter_size[RIGHT_GUTTER] /*
1385 *Width of right gutter.
1386 This is a specifier; use `set-specifier' to change it.
1388 See `default-gutter-height' for more information.
1390 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qgutter_size);
1391 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
1392 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
1393 gutter_geometry_changed_in_window, 0, 0, 1);
1397 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1400 fb = Fcons (Fcons (list1 (Qgtk), Qautodetect), fb);
1402 #ifdef HAVE_X_WINDOWS
1403 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
1405 #ifdef HAVE_MS_WINDOWS
1406 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
1407 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1410 set_specifier_fallback (Vdefault_gutter_height, fb);
1414 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1416 #ifdef HAVE_X_WINDOWS
1417 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb);
1420 fb = Fcons (Fcons (list1 (Qgtk), Qautodetect), fb);
1422 #ifdef HAVE_MS_WINDOWS
1423 fb = Fcons (Fcons (list1 (Qmsprinter), Qautodetect), fb);
1424 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb);
1427 set_specifier_fallback (Vdefault_gutter_width, fb);
1429 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height);
1430 fb = list1 (Fcons (Qnil, Qzero));
1431 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb);
1432 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb);
1433 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb);
1435 DEFVAR_SPECIFIER ("default-gutter-border-width",
1436 &Vdefault_gutter_border_width /*
1437 *Width of the border around the default gutter.
1438 This is a specifier; use `set-specifier' to change it.
1440 The position of the default gutter is specified by the function
1441 `set-default-gutter-position'. If the corresponding position-specific
1442 gutter border width specifier (e.g. `top-gutter-border-width' if
1443 `default-gutter-position' is 'top) does not specify a border width in a
1444 particular domain (a window or a frame), then the value of
1445 `default-gutter-border-width' in that domain, if any, will be used
1449 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum);
1450 set_specifier_caching (Vdefault_gutter_border_width,
1451 offsetof (struct window, default_gutter_border_width),
1452 default_gutter_border_width_changed_in_window,
1455 DEFVAR_SPECIFIER ("top-gutter-border-width",
1456 &Vgutter_border_width[TOP_GUTTER] /*
1457 *Border width of the top gutter.
1458 This is a specifier; use `set-specifier' to change it.
1460 See `default-gutter-height' for more information.
1462 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1463 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1464 offsetof (struct window,
1465 gutter_border_width[TOP_GUTTER]),
1466 gutter_geometry_changed_in_window, 0, 0, 0);
1468 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1469 &Vgutter_border_width[BOTTOM_GUTTER] /*
1470 *Border width of the bottom gutter.
1471 This is a specifier; use `set-specifier' to change it.
1473 See `default-gutter-height' for more information.
1475 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1476 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1477 offsetof (struct window,
1478 gutter_border_width[BOTTOM_GUTTER]),
1479 gutter_geometry_changed_in_window, 0, 0, 0);
1481 DEFVAR_SPECIFIER ("left-gutter-border-width",
1482 &Vgutter_border_width[LEFT_GUTTER] /*
1483 *Border width of left gutter.
1484 This is a specifier; use `set-specifier' to change it.
1486 See `default-gutter-height' for more information.
1488 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1489 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1490 offsetof (struct window,
1491 gutter_border_width[LEFT_GUTTER]),
1492 gutter_geometry_changed_in_window, 0, 0, 0);
1494 DEFVAR_SPECIFIER ("right-gutter-border-width",
1495 &Vgutter_border_width[RIGHT_GUTTER] /*
1496 *Border width of right gutter.
1497 This is a specifier; use `set-specifier' to change it.
1499 See `default-gutter-height' for more information.
1501 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1502 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1503 offsetof (struct window,
1504 gutter_border_width[RIGHT_GUTTER]),
1505 gutter_geometry_changed_in_window, 0, 0, 0);
1509 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1511 #ifdef HAVE_X_WINDOWS
1512 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1514 #ifdef HAVE_MS_WINDOWS
1515 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb);
1516 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb);
1519 set_specifier_fallback (Vdefault_gutter_border_width, fb);
1521 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width);
1522 fb = list1 (Fcons (Qnil, Qzero));
1523 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb);
1524 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb);
1525 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb);
1527 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /*
1528 *Whether the default gutter is visible.
1529 This is a specifier; use `set-specifier' to change it.
1531 The position of the default gutter is specified by the function
1532 `set-default-gutter-position'. If the corresponding position-specific
1533 gutter visibility specifier (e.g. `top-gutter-visible-p' if
1534 `default-gutter-position' is 'top) does not specify a visible-p value
1535 in a particular domain (a window or a frame), then the value of
1536 `default-gutter-visible-p' in that domain, if any, will be used
1539 `default-gutter-visible-p' and all of the position-specific gutter
1540 visibility specifiers have a fallback value of true.
1542 Vdefault_gutter_visible_p = Fmake_specifier (Qgutter_visible);
1543 set_specifier_caching (Vdefault_gutter_visible_p,
1544 offsetof (struct window,
1545 default_gutter_visible_p),
1546 default_gutter_visible_p_changed_in_window,
1549 DEFVAR_SPECIFIER ("top-gutter-visible-p",
1550 &Vgutter_visible_p[TOP_GUTTER] /*
1551 *Whether the top gutter is visible.
1552 This is a specifier; use `set-specifier' to change it.
1554 See `default-gutter-visible-p' for more information.
1556 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qgutter_visible);
1557 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1558 offsetof (struct window,
1559 gutter_visible_p[TOP_GUTTER]),
1560 top_gutter_specs_changed, 0, 0, 0);
1562 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1563 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1564 *Whether the bottom gutter is visible.
1565 This is a specifier; use `set-specifier' to change it.
1567 See `default-gutter-visible-p' for more information.
1569 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_visible);
1570 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1571 offsetof (struct window,
1572 gutter_visible_p[BOTTOM_GUTTER]),
1573 bottom_gutter_specs_changed, 0, 0, 0);
1575 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1576 &Vgutter_visible_p[LEFT_GUTTER] /*
1577 *Whether the left gutter is visible.
1578 This is a specifier; use `set-specifier' to change it.
1580 See `default-gutter-visible-p' for more information.
1582 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qgutter_visible);
1583 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1584 offsetof (struct window,
1585 gutter_visible_p[LEFT_GUTTER]),
1586 left_gutter_specs_changed, 0, 0, 0);
1588 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1589 &Vgutter_visible_p[RIGHT_GUTTER] /*
1590 *Whether the right gutter is visible.
1591 This is a specifier; use `set-specifier' to change it.
1593 See `default-gutter-visible-p' for more information.
1595 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qgutter_visible);
1596 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1597 offsetof (struct window,
1598 gutter_visible_p[RIGHT_GUTTER]),
1599 right_gutter_specs_changed, 0, 0, 0);
1601 /* initially, top inherits from default; this can be
1602 changed with `set-default-gutter-position'. */
1603 fb = list1 (Fcons (Qnil, Qt));
1604 set_specifier_fallback (Vdefault_gutter_visible_p, fb);
1605 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER],
1606 Vdefault_gutter_visible_p);
1607 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb);
1608 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb);
1609 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb);