Mercurial > hg > xemacs-beta
comparison src/gutter.c @ 422:95016f13131a r21-2-19
Import from CVS: tag r21-2-19
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:25:01 +0200 |
parents | |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
421:fff06e11db74 | 422:95016f13131a |
---|---|
1 /* Gutter implementation. | |
2 Copyright (C) 1999 Andy Piper. | |
3 | |
4 This file is part of XEmacs. | |
5 | |
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 | |
9 later version. | |
10 | |
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 | |
14 for more details. | |
15 | |
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. */ | |
20 | |
21 /* Synched up with: Not in FSF. */ | |
22 | |
23 /* Specifers ripped-off from toolbar.c */ | |
24 | |
25 #include <config.h> | |
26 #include "lisp.h" | |
27 | |
28 #include "buffer.h" | |
29 #include "frame.h" | |
30 #include "device.h" | |
31 #include "faces.h" | |
32 #include "glyphs.h" | |
33 #include "redisplay.h" | |
34 #include "window.h" | |
35 #include "gutter.h" | |
36 | |
37 Lisp_Object Vgutter[4]; | |
38 Lisp_Object Vgutter_size[4]; | |
39 Lisp_Object Vgutter_visible_p[4]; | |
40 Lisp_Object Vgutter_border_width[4]; | |
41 | |
42 Lisp_Object Vdefault_gutter, Vdefault_gutter_visible_p; | |
43 Lisp_Object Vdefault_gutter_width, Vdefault_gutter_height; | |
44 Lisp_Object Vdefault_gutter_border_width; | |
45 | |
46 Lisp_Object Vdefault_gutter_position; | |
47 | |
48 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ | |
49 do { \ | |
50 switch (pos) \ | |
51 { \ | |
52 case TOP_GUTTER: \ | |
53 (frame)->top_gutter_was_visible = flag; \ | |
54 break; \ | |
55 case BOTTOM_GUTTER: \ | |
56 (frame)->bottom_gutter_was_visible = flag; \ | |
57 break; \ | |
58 case LEFT_GUTTER: \ | |
59 (frame)->left_gutter_was_visible = flag; \ | |
60 break; \ | |
61 case RIGHT_GUTTER: \ | |
62 (frame)->right_gutter_was_visible = flag; \ | |
63 break; \ | |
64 default: \ | |
65 abort (); \ | |
66 } \ | |
67 } while (0) | |
68 | |
69 static int gutter_was_visible (struct frame* frame, enum gutter_pos pos) | |
70 { | |
71 switch (pos) | |
72 { | |
73 case TOP_GUTTER: | |
74 return (frame)->top_gutter_was_visible; | |
75 case BOTTOM_GUTTER: | |
76 return (frame)->bottom_gutter_was_visible; | |
77 case LEFT_GUTTER: | |
78 return (frame)->left_gutter_was_visible; | |
79 case RIGHT_GUTTER: | |
80 return (frame)->right_gutter_was_visible; | |
81 default: | |
82 abort (); | |
83 } | |
84 } | |
85 | |
86 static Lisp_Object | |
87 frame_topmost_window (struct frame *f) | |
88 { | |
89 Lisp_Object w = FRAME_ROOT_WINDOW (f); | |
90 | |
91 do { | |
92 while (!NILP (XWINDOW (w)->vchild)) | |
93 { | |
94 w = XWINDOW (w)->vchild; | |
95 } | |
96 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild)); | |
97 | |
98 return w; | |
99 } | |
100 | |
101 static Lisp_Object | |
102 frame_bottommost_window (struct frame *f) | |
103 { | |
104 Lisp_Object w = FRAME_ROOT_WINDOW (f); | |
105 | |
106 do { | |
107 while (!NILP (XWINDOW (w)->vchild)) | |
108 { | |
109 w = XWINDOW (w)->vchild; | |
110 while (!NILP (XWINDOW (w)->next)) | |
111 { | |
112 w = XWINDOW (w)->next; | |
113 } | |
114 } | |
115 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild)); | |
116 | |
117 return w; | |
118 } | |
119 | |
120 #if 0 | |
121 static Lisp_Object | |
122 frame_leftmost_window (struct frame *f) | |
123 { | |
124 Lisp_Object w = FRAME_ROOT_WINDOW (f); | |
125 | |
126 do { | |
127 while (!NILP (XWINDOW (w)->hchild)) | |
128 { | |
129 w = XWINDOW (w)->hchild; | |
130 } | |
131 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild)); | |
132 | |
133 return w; | |
134 } | |
135 | |
136 static Lisp_Object | |
137 frame_rightmost_window (struct frame *f) | |
138 { | |
139 Lisp_Object w = FRAME_ROOT_WINDOW (f); | |
140 | |
141 do { | |
142 while (!NILP (XWINDOW (w)->hchild)) | |
143 { | |
144 w = XWINDOW (w)->hchild; | |
145 while (!NILP (XWINDOW (w)->next)) | |
146 { | |
147 w = XWINDOW (w)->next; | |
148 } | |
149 } | |
150 } while (!NILP (XWINDOW (w)->vchild) && !NILP (w = XWINDOW (w)->vchild)); | |
151 return w; | |
152 } | |
153 #endif | |
154 | |
155 /* calculate the coordinates of a gutter for the current frame and | |
156 selected window. we have to be careful in calculating this as we | |
157 need to use *two* windows, the currently selected window will give | |
158 us the actual height, width and contents of the gutter, but if we | |
159 use this for calculating the gutter positions we run into trouble | |
160 if it is not the window nearest the gutter. Instead we predetermine | |
161 the nearest window and then use that.*/ | |
162 void | |
163 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y, | |
164 int *width, int *height) | |
165 { | |
166 struct window | |
167 * top = XWINDOW (frame_topmost_window (f)), | |
168 * bot = XWINDOW (frame_bottommost_window (f)); | |
169 /* The top and bottom gutters take precedence over the left and | |
170 right. */ | |
171 switch (pos) | |
172 { | |
173 case TOP_GUTTER: | |
174 *x = FRAME_LEFT_BORDER_END (f); | |
175 *y = FRAME_TOP_BORDER_END (f); | |
176 *width = FRAME_RIGHT_BORDER_START (f) | |
177 - FRAME_LEFT_BORDER_END (f); | |
178 *height = FRAME_TOP_GUTTER_BOUNDS (f); | |
179 break; | |
180 | |
181 case BOTTOM_GUTTER: | |
182 *x = FRAME_LEFT_BORDER_END (f); | |
183 *y = WINDOW_BOTTOM (bot) | |
184 - FRAME_BOTTOM_GUTTER_BOUNDS (f); | |
185 *width = FRAME_RIGHT_BORDER_START (f) | |
186 - FRAME_LEFT_BORDER_END (f); | |
187 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f); | |
188 break; | |
189 | |
190 case LEFT_GUTTER: | |
191 *x = FRAME_LEFT_BORDER_END (f); | |
192 *y = WINDOW_TEXT_TOP (top); | |
193 *width = FRAME_LEFT_GUTTER_BOUNDS (f); | |
194 *height = WINDOW_BOTTOM (bot) | |
195 - (WINDOW_TEXT_TOP (top) | |
196 + FRAME_BOTTOM_GUTTER_BOUNDS (f)); | |
197 break; | |
198 | |
199 case RIGHT_GUTTER: | |
200 *x = FRAME_RIGHT_BORDER_START (f) | |
201 - FRAME_RIGHT_GUTTER_BOUNDS (f); | |
202 *y = WINDOW_TEXT_TOP (top); | |
203 *width = FRAME_RIGHT_GUTTER_BOUNDS (f); | |
204 *height = WINDOW_BOTTOM (bot) | |
205 - (WINDOW_TEXT_TOP (top) | |
206 + FRAME_BOTTOM_GUTTER_BOUNDS (f)); | |
207 break; | |
208 | |
209 default: | |
210 abort (); | |
211 } | |
212 } | |
213 | |
214 static void | |
215 output_gutter (struct frame *f, enum gutter_pos pos) | |
216 { | |
217 Lisp_Object frame; | |
218 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
219 struct device *d = XDEVICE (f->device); | |
220 struct window* w = XWINDOW (window); | |
221 int x, y, width, height, ypos; | |
222 int line; | |
223 int border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos); | |
224 face_index findex = get_builtin_face_cache_index (w, Vgui_element_face); | |
225 display_line_dynarr* ddla, *cdla; | |
226 struct display_line *dl; | |
227 | |
228 if (!f->current_display_lines) | |
229 f->current_display_lines = Dynarr_new (display_line); | |
230 if (!f->desired_display_lines) | |
231 f->desired_display_lines = Dynarr_new (display_line); | |
232 | |
233 ddla = f->desired_display_lines; | |
234 cdla = f->current_display_lines; | |
235 | |
236 XSETFRAME (frame, f); | |
237 | |
238 get_gutter_coords (f, pos, &x, &y, &width, &height); | |
239 /* clear out what we want to cover */ | |
240 /* generate some display lines */ | |
241 generate_displayable_area (w, WINDOW_GUTTER (w, pos), | |
242 x + border_width, y + border_width, | |
243 width - 2 * border_width, | |
244 height - 2 * border_width, ddla, 0, findex); | |
245 /* Output each line. */ | |
246 for (line = 0; line < Dynarr_length (ddla); line++) | |
247 { | |
248 output_display_line (w, cdla, ddla, line, -1, -1); | |
249 } | |
250 | |
251 /* grab coordinates of last line and blank after it. */ | |
252 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); | |
253 ypos = dl->ypos + dl->descent - dl->clip; | |
254 redisplay_clear_region (window, findex, x + border_width , ypos, | |
255 width - 2 * border_width, height - (ypos - y)); | |
256 | |
257 /* bevel the gutter area if so desired */ | |
258 if (border_width != 0) | |
259 { | |
260 MAYBE_DEVMETH (d, bevel_area, | |
261 (w, findex, x, y, width, height, border_width)); | |
262 } | |
263 } | |
264 | |
265 /* sizing gutters is a pain so we try and help the user by detemining | |
266 what height will accomodate all lines. This is useless on left and | |
267 right gutters as we always have a maximal number of lines. */ | |
268 static Lisp_Object | |
269 calculate_gutter_size (struct window *w, enum gutter_pos pos) | |
270 { | |
271 struct frame* f = XFRAME (WINDOW_FRAME (w)); | |
272 int ypos; | |
273 display_line_dynarr* ddla; | |
274 struct display_line *dl; | |
275 | |
276 /* we cannot autodetect gutter sizes for the left and right as there | |
277 is no reasonable metric to use */ | |
278 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER); | |
279 /* degenerate case */ | |
280 if (NILP (WINDOW_GUTTER (w, pos)) | |
281 || | |
282 !FRAME_VISIBLE_P (f)) | |
283 return Qnil; | |
284 | |
285 ddla = Dynarr_new (display_line); | |
286 /* generate some display lines */ | |
287 generate_displayable_area (w, WINDOW_GUTTER (w, pos), | |
288 FRAME_LEFT_BORDER_END (f), | |
289 0, | |
290 FRAME_RIGHT_BORDER_START (f) | |
291 - FRAME_LEFT_BORDER_END (f), | |
292 200, | |
293 ddla, 0, 0); | |
294 /* grab coordinates of last line */ | |
295 if (Dynarr_length (ddla)) | |
296 { | |
297 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); | |
298 ypos = dl->ypos + dl->descent - dl->clip; | |
299 Dynarr_free (ddla); | |
300 return make_int (ypos); | |
301 } | |
302 else | |
303 { | |
304 Dynarr_free (ddla); | |
305 return Qnil; | |
306 } | |
307 } | |
308 | |
309 static void | |
310 clear_gutter (struct frame *f, enum gutter_pos pos) | |
311 { | |
312 int x, y, width, height; | |
313 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
314 face_index findex = get_builtin_face_cache_index (XWINDOW (window), | |
315 Vgui_element_face); | |
316 get_gutter_coords (f, pos, &x, &y, &width, &height); | |
317 | |
318 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0); | |
319 | |
320 redisplay_clear_region (window, findex, x, y, width, height); | |
321 } | |
322 | |
323 void | |
324 update_frame_gutters (struct frame *f) | |
325 { | |
326 if (f->gutter_changed || f->frame_changed || f->clear) | |
327 { | |
328 int pos; | |
329 /* and output */ | |
330 | |
331 for (pos = 0; pos < 4; pos++) | |
332 { | |
333 if (FRAME_GUTTER_VISIBLE (f, pos)) | |
334 output_gutter (f, pos); | |
335 else if (gutter_was_visible (f, pos)) | |
336 clear_gutter (f, pos); | |
337 } | |
338 | |
339 } | |
340 f->gutter_changed = 0; | |
341 } | |
342 | |
343 static void | |
344 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y, | |
345 int width, int height) | |
346 { | |
347 int g_x, g_y, g_width, g_height; | |
348 int newx, newy; | |
349 | |
350 get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height); | |
351 | |
352 if (((y + height) < g_y) || (y > (g_y + g_height))) | |
353 return; | |
354 if (((x + width) < g_x) || (x > (g_x + g_width))) | |
355 return; | |
356 | |
357 /* #### optimize this - redrawing the whole gutter for every expose | |
358 is very expensive. We reset the current display lines because if | |
359 they're being exposed they are no longer current. */ | |
360 if (f->current_display_lines) | |
361 Dynarr_reset (f->current_display_lines); | |
362 /* we have to do this in-case there were subwindows where we are | |
363 redrawing, unfortunately sometimes this also generates expose | |
364 events resulting in an endless cycle of redsplay. */ | |
365 newx = max (x, g_x); | |
366 newy = max (y, g_y); | |
367 width = min (x + width - newx, g_x + g_width - newx); | |
368 height = min (y + height - newy, g_y + g_height - newy); | |
369 redisplay_unmap_subwindows_maybe (f, newx, newy, width, height); | |
370 | |
371 /* Even if none of the gutter is in the area, the blank region at | |
372 the very least must be because the first thing we did is verify | |
373 that some portion of the gutter is in the exposed region. */ | |
374 output_gutter (f, pos); | |
375 } | |
376 | |
377 void | |
378 redraw_exposed_gutters (struct frame *f, int x, int y, int width, | |
379 int height) | |
380 { | |
381 int pos; | |
382 for (pos = 0; pos < 4; pos++) | |
383 { | |
384 if (FRAME_GUTTER_VISIBLE (f, pos)) | |
385 redraw_exposed_gutter (f, pos, x, y, width, height); | |
386 } | |
387 } | |
388 | |
389 void | |
390 free_frame_gutters (struct frame *f) | |
391 { | |
392 if (f->current_display_lines) | |
393 Dynarr_free (f->current_display_lines); | |
394 if (f->desired_display_lines) | |
395 Dynarr_free (f->desired_display_lines); | |
396 } | |
397 | |
398 static enum gutter_pos | |
399 decode_gutter_position (Lisp_Object position) | |
400 { | |
401 if (EQ (position, Qtop)) return TOP_GUTTER; | |
402 if (EQ (position, Qbottom)) return BOTTOM_GUTTER; | |
403 if (EQ (position, Qleft)) return LEFT_GUTTER; | |
404 if (EQ (position, Qright)) return RIGHT_GUTTER; | |
405 signal_simple_error ("Invalid gutter position", position); | |
406 | |
407 return TOP_GUTTER; /* not reached */ | |
408 } | |
409 | |
410 DEFUN ("set-default-gutter-position", Fset_default_gutter_position, 1, 1, 0, /* | |
411 Set the position that the `default-gutter' will be displayed at. | |
412 Valid positions are 'top, 'bottom, 'left and 'right. | |
413 See `default-gutter-position'. | |
414 */ | |
415 (position)) | |
416 { | |
417 enum gutter_pos cur = decode_gutter_position (Vdefault_gutter_position); | |
418 enum gutter_pos new = decode_gutter_position (position); | |
419 | |
420 if (cur != new) | |
421 { | |
422 /* The following calls will automatically cause the dirty | |
423 flags to be set; we delay frame size changes to avoid | |
424 lots of frame flickering. */ | |
425 /* #### I think this should be GC protected. -sb */ | |
426 hold_frame_size_changes (); | |
427 set_specifier_fallback (Vgutter[cur], list1 (Fcons (Qnil, Qnil))); | |
428 set_specifier_fallback (Vgutter[new], Vdefault_gutter); | |
429 set_specifier_fallback (Vgutter_size[cur], list1 (Fcons (Qnil, Qzero))); | |
430 set_specifier_fallback (Vgutter_size[new], | |
431 new == TOP_GUTTER || new == BOTTOM_GUTTER | |
432 ? Vdefault_gutter_height | |
433 : Vdefault_gutter_width); | |
434 set_specifier_fallback (Vgutter_border_width[cur], | |
435 list1 (Fcons (Qnil, Qzero))); | |
436 set_specifier_fallback (Vgutter_border_width[new], | |
437 Vdefault_gutter_border_width); | |
438 set_specifier_fallback (Vgutter_visible_p[cur], | |
439 list1 (Fcons (Qnil, Qt))); | |
440 set_specifier_fallback (Vgutter_visible_p[new], | |
441 Vdefault_gutter_visible_p); | |
442 Vdefault_gutter_position = position; | |
443 unhold_frame_size_changes (); | |
444 } | |
445 | |
446 return position; | |
447 } | |
448 | |
449 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /* | |
450 Return the position that the `default-gutter' will be displayed at. | |
451 The `default-gutter' will only be displayed here if the corresponding | |
452 position-specific gutter specifier does not provide a value. | |
453 */ | |
454 ()) | |
455 { | |
456 return Vdefault_gutter_position; | |
457 } | |
458 | |
459 DEFUN ("gutter-pixel-width", Fgutter_pixel_width, 0, 2, 0, /* | |
460 Return the pixel width of the gutter at POS in LOCALE. | |
461 POS defaults to the default gutter position. LOCALE defaults to | |
462 the current window. | |
463 */ | |
464 (pos, locale)) | |
465 { | |
466 int x, y, width, height; | |
467 enum gutter_pos p = TOP_GUTTER; | |
468 struct frame *f = decode_frame (FW_FRAME (locale)); | |
469 | |
470 if (NILP (pos)) | |
471 pos = Vdefault_gutter_position; | |
472 p = decode_gutter_position (pos); | |
473 | |
474 get_gutter_coords (f, p, &x, &y, &width, &height); | |
475 width -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2); | |
476 | |
477 return make_int (width); | |
478 } | |
479 | |
480 DEFUN ("gutter-pixel-height", Fgutter_pixel_height, 0, 2, 0, /* | |
481 Return the pixel height of the gutter at POS in LOCALE. | |
482 POS defaults to the default gutter position. LOCALE defaults to | |
483 the current window. | |
484 */ | |
485 (pos, locale)) | |
486 { | |
487 int x, y, width, height; | |
488 enum gutter_pos p = TOP_GUTTER; | |
489 struct frame *f = decode_frame (FW_FRAME (locale)); | |
490 | |
491 if (NILP (pos)) | |
492 pos = Vdefault_gutter_position; | |
493 p = decode_gutter_position (pos); | |
494 | |
495 get_gutter_coords (f, p, &x, &y, &width, &height); | |
496 height -= (FRAME_GUTTER_BORDER_WIDTH (f, p) * 2); | |
497 | |
498 return make_int (height); | |
499 } | |
500 | |
501 DEFINE_SPECIFIER_TYPE (gutter); | |
502 | |
503 static void | |
504 gutter_after_change (Lisp_Object specifier, Lisp_Object locale) | |
505 { | |
506 MARK_GUTTER_CHANGED; | |
507 } | |
508 | |
509 static void | |
510 gutter_validate (Lisp_Object instantiator) | |
511 { | |
512 if (NILP (instantiator)) | |
513 return; | |
514 | |
515 if (!STRINGP (instantiator)) | |
516 signal_simple_error ("Gutter spec must be string or nil", instantiator); | |
517 } | |
518 | |
519 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /* | |
520 Return non-nil if OBJECT is a gutter specifier. | |
521 Gutter specifiers are used to specify the format of a gutter. | |
522 The values of the variables `default-gutter', `top-gutter', | |
523 `left-gutter', `right-gutter', and `bottom-gutter' are always | |
524 gutter specifiers. | |
525 | |
526 Valid gutter instantiators are called "gutter descriptors" | |
527 and are lists of vectors. See `default-gutter' for a description | |
528 of the exact format. | |
529 */ | |
530 (object)) | |
531 { | |
532 return GUTTER_SPECIFIERP (object) ? Qt : Qnil; | |
533 } | |
534 | |
535 | |
536 /* | |
537 Helper for invalidating the real specifier when default | |
538 specifier caching changes | |
539 */ | |
540 static void | |
541 recompute_overlaying_specifier (Lisp_Object real_one[4]) | |
542 { | |
543 enum gutter_pos pos = decode_gutter_position (Vdefault_gutter_position); | |
544 Fset_specifier_dirty_flag (real_one[pos]); | |
545 } | |
546 | |
547 static void | |
548 gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
549 Lisp_Object oldval) | |
550 { | |
551 int pos; | |
552 for (pos = 0; pos< 4; pos++) | |
553 { | |
554 w->real_gutter_size[pos] = w->gutter_size[pos]; | |
555 if (EQ (w->real_gutter_size[pos], Qautodetect) | |
556 && !NILP (w->gutter_visible_p[pos])) | |
557 { | |
558 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | |
559 } | |
560 } | |
561 MARK_GUTTER_CHANGED; | |
562 MARK_WINDOWS_CHANGED (w); | |
563 } | |
564 | |
565 static void | |
566 default_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
567 Lisp_Object oldval) | |
568 { | |
569 recompute_overlaying_specifier (Vgutter); | |
570 } | |
571 | |
572 static void | |
573 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w, | |
574 Lisp_Object oldval) | |
575 { | |
576 int pos; | |
577 for (pos = 0; pos< 4; pos++) | |
578 { | |
579 w->real_gutter_size[pos] = w->gutter_size[pos]; | |
580 if (EQ (w->real_gutter_size[pos], Qautodetect) | |
581 && !NILP (w->gutter_visible_p[pos])) | |
582 { | |
583 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | |
584 } | |
585 } | |
586 | |
587 MARK_GUTTER_CHANGED; | |
588 MARK_WINDOWS_CHANGED (w); | |
589 } | |
590 | |
591 static void | |
592 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w, | |
593 Lisp_Object oldval) | |
594 { | |
595 recompute_overlaying_specifier (Vgutter_size); | |
596 } | |
597 | |
598 static void | |
599 default_gutter_border_width_changed_in_window (Lisp_Object specifier, | |
600 struct window *w, | |
601 Lisp_Object oldval) | |
602 { | |
603 recompute_overlaying_specifier (Vgutter_border_width); | |
604 } | |
605 | |
606 static void | |
607 default_gutter_visible_p_changed_in_window (Lisp_Object specifier, | |
608 struct window *w, | |
609 Lisp_Object oldval) | |
610 { | |
611 recompute_overlaying_specifier (Vgutter_visible_p); | |
612 } | |
613 | |
614 void | |
615 init_frame_gutters (struct frame *f) | |
616 { | |
617 int pos; | |
618 struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); | |
619 /* We are here as far in frame creation so cached specifiers are | |
620 already recomputed, and possibly modified by resource | |
621 initialization. We need to recalculate autodetected gutters. */ | |
622 for (pos = 0; pos< 4; pos++) | |
623 { | |
624 w->real_gutter_size[pos] = w->gutter_size[pos]; | |
625 if (EQ (w->gutter_size[pos], Qautodetect) | |
626 && !NILP (w->gutter_visible_p[pos])) | |
627 { | |
628 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | |
629 MARK_GUTTER_CHANGED; | |
630 MARK_WINDOWS_CHANGED (w); | |
631 } | |
632 } | |
633 } | |
634 | |
635 void | |
636 syms_of_gutter (void) | |
637 { | |
638 DEFSUBR (Fgutter_specifier_p); | |
639 DEFSUBR (Fset_default_gutter_position); | |
640 DEFSUBR (Fdefault_gutter_position); | |
641 DEFSUBR (Fgutter_pixel_height); | |
642 DEFSUBR (Fgutter_pixel_width); | |
643 } | |
644 | |
645 void | |
646 vars_of_gutter (void) | |
647 { | |
648 staticpro (&Vdefault_gutter_position); | |
649 Vdefault_gutter_position = Qtop; | |
650 | |
651 Fprovide (Qgutter); | |
652 } | |
653 | |
654 void | |
655 specifier_type_create_gutter (void) | |
656 { | |
657 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p"); | |
658 | |
659 SPECIFIER_HAS_METHOD (gutter, validate); | |
660 SPECIFIER_HAS_METHOD (gutter, after_change); | |
661 } | |
662 | |
663 void | |
664 specifier_vars_of_gutter (void) | |
665 { | |
666 Lisp_Object fb; | |
667 | |
668 DEFVAR_SPECIFIER ("default-gutter", &Vdefault_gutter /* | |
669 Specifier for a fallback gutter. | |
670 Use `set-specifier' to change this. | |
671 | |
672 The position of this gutter is specified in the function | |
673 `default-gutter-position'. If the corresponding position-specific | |
674 gutter (e.g. `top-gutter' if `default-gutter-position' is 'top) | |
675 does not specify a gutter in a particular domain (usually a window), | |
676 then the value of `default-gutter' in that domain, if any, will be | |
677 used instead. | |
678 | |
679 Note that the gutter at any particular position will not be | |
680 displayed unless its visibility flag is true and its thickness | |
681 \(width or height, depending on orientation) is non-zero. The | |
682 visibility is controlled by the specifiers `top-gutter-visible-p', | |
683 `bottom-gutter-visible-p', `left-gutter-visible-p', and | |
684 `right-gutter-visible-p', and the thickness is controlled by the | |
685 specifiers `top-gutter-height', `bottom-gutter-height', | |
686 `left-gutter-width', and `right-gutter-width'. | |
687 | |
688 Note that one of the four visibility specifiers inherits from | |
689 `default-gutter-visibility' and one of the four thickness | |
690 specifiers inherits from either `default-gutter-width' or | |
691 `default-gutter-height' (depending on orientation), just | |
692 like for the gutter description specifiers (e.g. `top-gutter') | |
693 mentioned above. | |
694 | |
695 Therefore, if you are setting `default-gutter', you should control | |
696 the visibility and thickness using `default-gutter-visible-p', | |
697 `default-gutter-width', and `default-gutter-height', rather than | |
698 using position-specific specifiers. That way, you will get sane | |
699 behavior if the user changes the default gutter position. | |
700 | |
701 The gutter value should be a string or nil. You can attach extents and | |
702 glyphs to the string and hence display glyphs and text in other fonts | |
703 in the gutter area. | |
704 | |
705 */ ); | |
706 | |
707 Vdefault_gutter = Fmake_specifier (Qgutter); | |
708 /* #### It would be even nicer if the specifier caching | |
709 automatically knew about specifier fallbacks, so we didn't | |
710 have to do it ourselves. */ | |
711 set_specifier_caching (Vdefault_gutter, | |
712 slot_offset (struct window, | |
713 default_gutter), | |
714 default_gutter_specs_changed, | |
715 0, 0); | |
716 | |
717 DEFVAR_SPECIFIER ("top-gutter", | |
718 &Vgutter[TOP_GUTTER] /* | |
719 Specifier for the gutter at the top of the frame. | |
720 Use `set-specifier' to change this. | |
721 See `default-gutter' for a description of a valid gutter instantiator. | |
722 */ ); | |
723 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter); | |
724 set_specifier_caching (Vgutter[TOP_GUTTER], | |
725 slot_offset (struct window, | |
726 gutter[TOP_GUTTER]), | |
727 gutter_specs_changed, | |
728 0, 0); | |
729 | |
730 DEFVAR_SPECIFIER ("bottom-gutter", | |
731 &Vgutter[BOTTOM_GUTTER] /* | |
732 Specifier for the gutter at the bottom of the frame. | |
733 Use `set-specifier' to change this. | |
734 See `default-gutter' for a description of a valid gutter instantiator. | |
735 | |
736 Note that, unless the `default-gutter-position' is `bottom', by | |
737 default the height of the bottom gutter (controlled by | |
738 `bottom-gutter-height') is 0; thus, a bottom gutter will not be | |
739 displayed even if you provide a value for `bottom-gutter'. | |
740 */ ); | |
741 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter); | |
742 set_specifier_caching (Vgutter[BOTTOM_GUTTER], | |
743 slot_offset (struct window, | |
744 gutter[BOTTOM_GUTTER]), | |
745 gutter_specs_changed, | |
746 0, 0); | |
747 | |
748 DEFVAR_SPECIFIER ("left-gutter", | |
749 &Vgutter[LEFT_GUTTER] /* | |
750 Specifier for the gutter at the left edge of the frame. | |
751 Use `set-specifier' to change this. | |
752 See `default-gutter' for a description of a valid gutter instantiator. | |
753 | |
754 Note that, unless the `default-gutter-position' is `left', by | |
755 default the height of the left gutter (controlled by | |
756 `left-gutter-width') is 0; thus, a left gutter will not be | |
757 displayed even if you provide a value for `left-gutter'. | |
758 */ ); | |
759 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter); | |
760 set_specifier_caching (Vgutter[LEFT_GUTTER], | |
761 slot_offset (struct window, | |
762 gutter[LEFT_GUTTER]), | |
763 gutter_specs_changed, | |
764 0, 0); | |
765 | |
766 DEFVAR_SPECIFIER ("right-gutter", | |
767 &Vgutter[RIGHT_GUTTER] /* | |
768 Specifier for the gutter at the right edge of the frame. | |
769 Use `set-specifier' to change this. | |
770 See `default-gutter' for a description of a valid gutter instantiator. | |
771 | |
772 Note that, unless the `default-gutter-position' is `right', by | |
773 default the height of the right gutter (controlled by | |
774 `right-gutter-width') is 0; thus, a right gutter will not be | |
775 displayed even if you provide a value for `right-gutter'. | |
776 */ ); | |
777 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter); | |
778 set_specifier_caching (Vgutter[RIGHT_GUTTER], | |
779 slot_offset (struct window, | |
780 gutter[RIGHT_GUTTER]), | |
781 gutter_specs_changed, | |
782 0, 0); | |
783 | |
784 /* initially, top inherits from default; this can be | |
785 changed with `set-default-gutter-position'. */ | |
786 fb = list1 (Fcons (Qnil, Qnil)); | |
787 set_specifier_fallback (Vdefault_gutter, fb); | |
788 set_specifier_fallback (Vgutter[TOP_GUTTER], Vdefault_gutter); | |
789 set_specifier_fallback (Vgutter[BOTTOM_GUTTER], fb); | |
790 set_specifier_fallback (Vgutter[LEFT_GUTTER], fb); | |
791 set_specifier_fallback (Vgutter[RIGHT_GUTTER], fb); | |
792 | |
793 DEFVAR_SPECIFIER ("default-gutter-height", &Vdefault_gutter_height /* | |
794 *Height of the default gutter, if it's oriented horizontally. | |
795 This is a specifier; use `set-specifier' to change it. | |
796 | |
797 The position of the default gutter is specified by the function | |
798 `set-default-gutter-position'. If the corresponding position-specific | |
799 gutter thickness specifier (e.g. `top-gutter-height' if | |
800 `default-gutter-position' is 'top) does not specify a thickness in a | |
801 particular domain (a window or a frame), then the value of | |
802 `default-gutter-height' or `default-gutter-width' (depending on the | |
803 gutter orientation) in that domain, if any, will be used instead. | |
804 | |
805 Note that `default-gutter-height' is only used when | |
806 `default-gutter-position' is 'top or 'bottom, and `default-gutter-width' | |
807 is only used when `default-gutter-position' is 'left or 'right. | |
808 | |
809 Note that all of the position-specific gutter thickness specifiers | |
810 have a fallback value of zero when they do not correspond to the | |
811 default gutter. Therefore, you will have to set a non-zero thickness | |
812 value if you want a position-specific gutter to be displayed. | |
813 | |
814 If you set the height to 'autodetect the size of the gutter will be | |
815 calculated to be large enough to hold the contents of the gutter. This | |
816 is the default. | |
817 */ ); | |
818 Vdefault_gutter_height = Fmake_specifier (Qgeneric); | |
819 set_specifier_caching (Vdefault_gutter_height, | |
820 slot_offset (struct window, | |
821 default_gutter_height), | |
822 default_gutter_size_changed_in_window, | |
823 0, 0); | |
824 | |
825 DEFVAR_SPECIFIER ("default-gutter-width", &Vdefault_gutter_width /* | |
826 *Width of the default gutter, if it's oriented vertically. | |
827 This is a specifier; use `set-specifier' to change it. | |
828 | |
829 See `default-gutter-height' for more information. | |
830 */ ); | |
831 Vdefault_gutter_width = Fmake_specifier (Qnatnum); | |
832 set_specifier_caching (Vdefault_gutter_width, | |
833 slot_offset (struct window, | |
834 default_gutter_width), | |
835 default_gutter_size_changed_in_window, | |
836 0, 0); | |
837 | |
838 DEFVAR_SPECIFIER ("top-gutter-height", | |
839 &Vgutter_size[TOP_GUTTER] /* | |
840 *Height of the top gutter. | |
841 This is a specifier; use `set-specifier' to change it. | |
842 | |
843 See `default-gutter-height' for more information. | |
844 */ ); | |
845 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgeneric); | |
846 set_specifier_caching (Vgutter_size[TOP_GUTTER], | |
847 slot_offset (struct window, | |
848 gutter_size[TOP_GUTTER]), | |
849 gutter_geometry_changed_in_window, | |
850 0, 0); | |
851 | |
852 DEFVAR_SPECIFIER ("bottom-gutter-height", | |
853 &Vgutter_size[BOTTOM_GUTTER] /* | |
854 *Height of the bottom gutter. | |
855 This is a specifier; use `set-specifier' to change it. | |
856 | |
857 See `default-gutter-height' for more information. | |
858 */ ); | |
859 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgeneric); | |
860 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER], | |
861 slot_offset (struct window, | |
862 gutter_size[BOTTOM_GUTTER]), | |
863 gutter_geometry_changed_in_window, | |
864 0, 0); | |
865 | |
866 DEFVAR_SPECIFIER ("left-gutter-width", | |
867 &Vgutter_size[LEFT_GUTTER] /* | |
868 *Width of left gutter. | |
869 This is a specifier; use `set-specifier' to change it. | |
870 | |
871 See `default-gutter-height' for more information. | |
872 */ ); | |
873 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum); | |
874 set_specifier_caching (Vgutter_size[LEFT_GUTTER], | |
875 slot_offset (struct window, | |
876 gutter_size[LEFT_GUTTER]), | |
877 gutter_geometry_changed_in_window, | |
878 0, 0); | |
879 | |
880 DEFVAR_SPECIFIER ("right-gutter-width", | |
881 &Vgutter_size[RIGHT_GUTTER] /* | |
882 *Width of right gutter. | |
883 This is a specifier; use `set-specifier' to change it. | |
884 | |
885 See `default-gutter-height' for more information. | |
886 */ ); | |
887 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); | |
888 set_specifier_caching (Vgutter_size[RIGHT_GUTTER], | |
889 slot_offset (struct window, | |
890 gutter_size[RIGHT_GUTTER]), | |
891 gutter_geometry_changed_in_window, | |
892 0, 0); | |
893 | |
894 fb = Qnil; | |
895 #ifdef HAVE_TTY | |
896 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb); | |
897 #endif | |
898 #ifdef HAVE_X_WINDOWS | |
899 fb = Fcons (Fcons (list1 (Qx), Qautodetect), fb); | |
900 #endif | |
901 #ifdef HAVE_MS_WINDOWS | |
902 fb = Fcons (Fcons (list1 (Qmswindows), Qautodetect), fb); | |
903 #endif | |
904 if (!NILP (fb)) | |
905 set_specifier_fallback (Vdefault_gutter_height, fb); | |
906 | |
907 fb = Qnil; | |
908 #ifdef HAVE_TTY | |
909 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); | |
910 #endif | |
911 #ifdef HAVE_X_WINDOWS | |
912 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb); | |
913 #endif | |
914 #ifdef HAVE_MS_WINDOWS | |
915 fb = Fcons (Fcons (list1 (Qmswindows), | |
916 make_int (DEFAULT_GUTTER_WIDTH)), fb); | |
917 #endif | |
918 if (!NILP (fb)) | |
919 set_specifier_fallback (Vdefault_gutter_width, fb); | |
920 | |
921 set_specifier_fallback (Vgutter_size[TOP_GUTTER], Vdefault_gutter_height); | |
922 fb = list1 (Fcons (Qnil, Qzero)); | |
923 set_specifier_fallback (Vgutter_size[BOTTOM_GUTTER], fb); | |
924 set_specifier_fallback (Vgutter_size[LEFT_GUTTER], fb); | |
925 set_specifier_fallback (Vgutter_size[RIGHT_GUTTER], fb); | |
926 | |
927 DEFVAR_SPECIFIER ("default-gutter-border-width", | |
928 &Vdefault_gutter_border_width /* | |
929 *Width of the border around the default gutter. | |
930 This is a specifier; use `set-specifier' to change it. | |
931 | |
932 The position of the default gutter is specified by the function | |
933 `set-default-gutter-position'. If the corresponding position-specific | |
934 gutter border width specifier (e.g. `top-gutter-border-width' if | |
935 `default-gutter-position' is 'top) does not specify a border width in a | |
936 particular domain (a window or a frame), then the value of | |
937 `default-gutter-border-width' in that domain, if any, will be used | |
938 instead. | |
939 | |
940 */ ); | |
941 Vdefault_gutter_border_width = Fmake_specifier (Qnatnum); | |
942 set_specifier_caching (Vdefault_gutter_border_width, | |
943 slot_offset (struct window, | |
944 default_gutter_border_width), | |
945 default_gutter_border_width_changed_in_window, | |
946 0, 0); | |
947 | |
948 DEFVAR_SPECIFIER ("top-gutter-border-width", | |
949 &Vgutter_border_width[TOP_GUTTER] /* | |
950 *Border width of the top gutter. | |
951 This is a specifier; use `set-specifier' to change it. | |
952 | |
953 See `default-gutter-height' for more information. | |
954 */ ); | |
955 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum); | |
956 set_specifier_caching (Vgutter_border_width[TOP_GUTTER], | |
957 slot_offset (struct window, | |
958 gutter_border_width[TOP_GUTTER]), | |
959 gutter_geometry_changed_in_window, | |
960 0, 0); | |
961 | |
962 DEFVAR_SPECIFIER ("bottom-gutter-border-width", | |
963 &Vgutter_border_width[BOTTOM_GUTTER] /* | |
964 *Border width of the bottom gutter. | |
965 This is a specifier; use `set-specifier' to change it. | |
966 | |
967 See `default-gutter-height' for more information. | |
968 */ ); | |
969 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum); | |
970 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER], | |
971 slot_offset (struct window, | |
972 gutter_border_width[BOTTOM_GUTTER]), | |
973 gutter_geometry_changed_in_window, | |
974 0, 0); | |
975 | |
976 DEFVAR_SPECIFIER ("left-gutter-border-width", | |
977 &Vgutter_border_width[LEFT_GUTTER] /* | |
978 *Border width of left gutter. | |
979 This is a specifier; use `set-specifier' to change it. | |
980 | |
981 See `default-gutter-height' for more information. | |
982 */ ); | |
983 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum); | |
984 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER], | |
985 slot_offset (struct window, | |
986 gutter_border_width[LEFT_GUTTER]), | |
987 gutter_geometry_changed_in_window, | |
988 0, 0); | |
989 | |
990 DEFVAR_SPECIFIER ("right-gutter-border-width", | |
991 &Vgutter_border_width[RIGHT_GUTTER] /* | |
992 *Border width of right gutter. | |
993 This is a specifier; use `set-specifier' to change it. | |
994 | |
995 See `default-gutter-height' for more information. | |
996 */ ); | |
997 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); | |
998 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER], | |
999 slot_offset (struct window, | |
1000 gutter_border_width[RIGHT_GUTTER]), | |
1001 gutter_geometry_changed_in_window, | |
1002 0, 0); | |
1003 | |
1004 fb = Qnil; | |
1005 #ifdef HAVE_TTY | |
1006 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); | |
1007 #endif | |
1008 #ifdef HAVE_X_WINDOWS | |
1009 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb); | |
1010 #endif | |
1011 #ifdef HAVE_MS_WINDOWS | |
1012 fb = Fcons (Fcons (list1 (Qmswindows), make_int (DEFAULT_GUTTER_BORDER_WIDTH)), fb); | |
1013 #endif | |
1014 if (!NILP (fb)) | |
1015 set_specifier_fallback (Vdefault_gutter_border_width, fb); | |
1016 | |
1017 set_specifier_fallback (Vgutter_border_width[TOP_GUTTER], Vdefault_gutter_border_width); | |
1018 fb = list1 (Fcons (Qnil, Qzero)); | |
1019 set_specifier_fallback (Vgutter_border_width[BOTTOM_GUTTER], fb); | |
1020 set_specifier_fallback (Vgutter_border_width[LEFT_GUTTER], fb); | |
1021 set_specifier_fallback (Vgutter_border_width[RIGHT_GUTTER], fb); | |
1022 | |
1023 DEFVAR_SPECIFIER ("default-gutter-visible-p", &Vdefault_gutter_visible_p /* | |
1024 *Whether the default gutter is visible. | |
1025 This is a specifier; use `set-specifier' to change it. | |
1026 | |
1027 The position of the default gutter is specified by the function | |
1028 `set-default-gutter-position'. If the corresponding position-specific | |
1029 gutter visibility specifier (e.g. `top-gutter-visible-p' if | |
1030 `default-gutter-position' is 'top) does not specify a visible-p value | |
1031 in a particular domain (a window or a frame), then the value of | |
1032 `default-gutter-visible-p' in that domain, if any, will be used | |
1033 instead. | |
1034 | |
1035 `default-gutter-visible-p' and all of the position-specific gutter | |
1036 visibility specifiers have a fallback value of true. | |
1037 */ ); | |
1038 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean); | |
1039 set_specifier_caching (Vdefault_gutter_visible_p, | |
1040 slot_offset (struct window, | |
1041 default_gutter_visible_p), | |
1042 default_gutter_visible_p_changed_in_window, | |
1043 0, 0); | |
1044 | |
1045 DEFVAR_SPECIFIER ("top-gutter-visible-p", | |
1046 &Vgutter_visible_p[TOP_GUTTER] /* | |
1047 *Whether the top gutter is visible. | |
1048 This is a specifier; use `set-specifier' to change it. | |
1049 | |
1050 See `default-gutter-visible-p' for more information. | |
1051 */ ); | |
1052 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean); | |
1053 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER], | |
1054 slot_offset (struct window, | |
1055 gutter_visible_p[TOP_GUTTER]), | |
1056 gutter_geometry_changed_in_window, | |
1057 0, 0); | |
1058 | |
1059 DEFVAR_SPECIFIER ("bottom-gutter-visible-p", | |
1060 &Vgutter_visible_p[BOTTOM_GUTTER] /* | |
1061 *Whether the bottom gutter is visible. | |
1062 This is a specifier; use `set-specifier' to change it. | |
1063 | |
1064 See `default-gutter-visible-p' for more information. | |
1065 */ ); | |
1066 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean); | |
1067 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER], | |
1068 slot_offset (struct window, | |
1069 gutter_visible_p[BOTTOM_GUTTER]), | |
1070 gutter_geometry_changed_in_window, | |
1071 0, 0); | |
1072 | |
1073 DEFVAR_SPECIFIER ("left-gutter-visible-p", | |
1074 &Vgutter_visible_p[LEFT_GUTTER] /* | |
1075 *Whether the left gutter is visible. | |
1076 This is a specifier; use `set-specifier' to change it. | |
1077 | |
1078 See `default-gutter-visible-p' for more information. | |
1079 */ ); | |
1080 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean); | |
1081 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER], | |
1082 slot_offset (struct window, | |
1083 gutter_visible_p[LEFT_GUTTER]), | |
1084 gutter_geometry_changed_in_window, | |
1085 0, 0); | |
1086 | |
1087 DEFVAR_SPECIFIER ("right-gutter-visible-p", | |
1088 &Vgutter_visible_p[RIGHT_GUTTER] /* | |
1089 *Whether the right gutter is visible. | |
1090 This is a specifier; use `set-specifier' to change it. | |
1091 | |
1092 See `default-gutter-visible-p' for more information. | |
1093 */ ); | |
1094 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean); | |
1095 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER], | |
1096 slot_offset (struct window, | |
1097 gutter_visible_p[RIGHT_GUTTER]), | |
1098 gutter_geometry_changed_in_window, | |
1099 0, 0); | |
1100 | |
1101 /* initially, top inherits from default; this can be | |
1102 changed with `set-default-gutter-position'. */ | |
1103 fb = list1 (Fcons (Qnil, Qt)); | |
1104 set_specifier_fallback (Vdefault_gutter_visible_p, fb); | |
1105 set_specifier_fallback (Vgutter_visible_p[TOP_GUTTER], | |
1106 Vdefault_gutter_visible_p); | |
1107 set_specifier_fallback (Vgutter_visible_p[BOTTOM_GUTTER], fb); | |
1108 set_specifier_fallback (Vgutter_visible_p[LEFT_GUTTER], fb); | |
1109 set_specifier_fallback (Vgutter_visible_p[RIGHT_GUTTER], fb); | |
1110 | |
1111 } |