Mercurial > hg > xemacs-beta
comparison src/gutter.c @ 442:abe6d1db359e r21-2-36
Import from CVS: tag r21-2-36
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:35:02 +0200 |
parents | 8de8e3f6228a |
children | 576fb035e263 |
comparison
equal
deleted
inserted
replaced
441:72a7cfa4a488 | 442:abe6d1db359e |
---|---|
1 /* Gutter implementation. | 1 /* Gutter implementation. |
2 Copyright (C) 1999 Andy Piper. | 2 Copyright (C) 1999, 2000 Andy Piper. |
3 | 3 |
4 This file is part of XEmacs. | 4 This file is part of XEmacs. |
5 | 5 |
6 XEmacs is free software; you can redistribute it and/or modify it | 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 | 7 under the terms of the GNU General Public License as published by the |
45 Lisp_Object Vdefault_gutter_border_width; | 45 Lisp_Object Vdefault_gutter_border_width; |
46 | 46 |
47 Lisp_Object Vdefault_gutter_position; | 47 Lisp_Object Vdefault_gutter_position; |
48 | 48 |
49 Lisp_Object Qgutter_size; | 49 Lisp_Object Qgutter_size; |
50 Lisp_Object Qgutter_visible; | |
51 Lisp_Object Qdefault_gutter_position_changed_hook; | |
52 | |
53 static void | |
54 update_gutter_geometry (struct frame *f, enum gutter_pos pos); | |
50 | 55 |
51 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ | 56 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ |
52 do { \ | 57 do { \ |
53 switch (pos) \ | 58 switch (pos) \ |
54 { \ | 59 { \ |
81 return frame->left_gutter_was_visible; | 86 return frame->left_gutter_was_visible; |
82 case RIGHT_GUTTER: | 87 case RIGHT_GUTTER: |
83 return frame->right_gutter_was_visible; | 88 return frame->right_gutter_was_visible; |
84 default: | 89 default: |
85 abort (); | 90 abort (); |
86 } | 91 return 0; /* To keep the compiler happy */ |
87 } | 92 } |
88 | 93 } |
94 | |
95 #if 0 | |
89 static Lisp_Object | 96 static Lisp_Object |
90 frame_topmost_window (struct frame *f) | 97 frame_topmost_window (struct frame *f) |
91 { | 98 { |
92 Lisp_Object w = FRAME_ROOT_WINDOW (f); | 99 Lisp_Object w = FRAME_ROOT_WINDOW (f); |
93 | 100 |
98 } | 105 } |
99 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild)); | 106 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild)); |
100 | 107 |
101 return w; | 108 return w; |
102 } | 109 } |
110 #endif | |
103 | 111 |
104 static Lisp_Object | 112 static Lisp_Object |
105 frame_bottommost_window (struct frame *f) | 113 frame_bottommost_window (struct frame *f) |
106 { | 114 { |
107 Lisp_Object w = FRAME_ROOT_WINDOW (f); | 115 Lisp_Object w = FRAME_ROOT_WINDOW (f); |
165 static void | 173 static void |
166 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y, | 174 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y, |
167 int *width, int *height) | 175 int *width, int *height) |
168 { | 176 { |
169 struct window | 177 struct window |
170 * top = XWINDOW (frame_topmost_window (f)), | |
171 * bot = XWINDOW (frame_bottommost_window (f)); | 178 * bot = XWINDOW (frame_bottommost_window (f)); |
172 /* The top and bottom gutters take precedence over the left and | 179 /* The top and bottom gutters take precedence over the left and |
173 right. */ | 180 right. */ |
174 switch (pos) | 181 switch (pos) |
175 { | 182 { |
176 case TOP_GUTTER: | 183 case TOP_GUTTER: |
177 *x = FRAME_LEFT_BORDER_END (f); | 184 *x = FRAME_LEFT_BORDER_END (f); |
178 *y = FRAME_TOP_BORDER_END (f); | 185 *y = FRAME_TOP_BORDER_END (f); |
179 *width = FRAME_RIGHT_BORDER_START (f) | 186 *width = FRAME_RIGHT_BORDER_START (f) |
180 - FRAME_LEFT_BORDER_END (f); | 187 - FRAME_LEFT_BORDER_END (f); |
181 *height = FRAME_TOP_GUTTER_BOUNDS (f); | 188 *height = FRAME_TOP_GUTTER_BOUNDS (f); |
182 break; | 189 break; |
183 | 190 |
184 case BOTTOM_GUTTER: | 191 case BOTTOM_GUTTER: |
185 *x = FRAME_LEFT_BORDER_END (f); | 192 *x = FRAME_LEFT_BORDER_END (f); |
186 *y = WINDOW_BOTTOM (bot) | 193 *y = WINDOW_BOTTOM (bot); |
187 - FRAME_BOTTOM_GUTTER_BOUNDS (f); | 194 *width = FRAME_RIGHT_BORDER_START (f) |
188 *width = FRAME_RIGHT_BORDER_START (f) | |
189 - FRAME_LEFT_BORDER_END (f); | 195 - FRAME_LEFT_BORDER_END (f); |
190 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f); | 196 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f); |
191 break; | 197 break; |
192 | 198 |
193 case LEFT_GUTTER: | 199 case LEFT_GUTTER: |
194 *x = FRAME_LEFT_BORDER_END (f); | 200 *x = FRAME_LEFT_BORDER_END (f); |
195 *y = WINDOW_TEXT_TOP (top); | 201 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f); |
196 *width = FRAME_LEFT_GUTTER_BOUNDS (f); | 202 *width = FRAME_LEFT_GUTTER_BOUNDS (f); |
197 *height = WINDOW_BOTTOM (bot) | 203 *height = WINDOW_BOTTOM (bot) |
198 - (WINDOW_TEXT_TOP (top) | 204 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f)); |
199 + FRAME_BOTTOM_GUTTER_BOUNDS (f)); | |
200 break; | 205 break; |
201 | 206 |
202 case RIGHT_GUTTER: | 207 case RIGHT_GUTTER: |
203 *x = FRAME_RIGHT_BORDER_START (f) | 208 *x = FRAME_RIGHT_BORDER_START (f) |
204 - FRAME_RIGHT_GUTTER_BOUNDS (f); | 209 - FRAME_RIGHT_GUTTER_BOUNDS (f); |
205 *y = WINDOW_TEXT_TOP (top); | 210 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f); |
206 *width = FRAME_RIGHT_GUTTER_BOUNDS (f); | 211 *width = FRAME_RIGHT_GUTTER_BOUNDS (f); |
207 *height = WINDOW_BOTTOM (bot) | 212 *height = WINDOW_BOTTOM (bot) |
208 - (WINDOW_TEXT_TOP (top) | 213 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f)); |
209 + FRAME_BOTTOM_GUTTER_BOUNDS (f)); | |
210 break; | 214 break; |
211 | 215 |
212 default: | 216 default: |
213 abort (); | 217 abort (); |
214 } | 218 } |
215 } | 219 } |
216 | 220 |
217 static void | 221 /* Convert the gutter specifier into something we can actually |
218 output_gutter (struct frame *f, enum gutter_pos pos) | 222 display. */ |
223 static Lisp_Object construct_window_gutter_spec (struct window* w, | |
224 enum gutter_pos pos) | |
225 { | |
226 Lisp_Object rest, *args; | |
227 int nargs = 0; | |
228 Lisp_Object gutter = RAW_WINDOW_GUTTER (w, pos); | |
229 | |
230 if (STRINGP (gutter) || NILP (gutter)) | |
231 return gutter; | |
232 | |
233 GET_LIST_LENGTH (gutter, nargs); | |
234 args = alloca_array (Lisp_Object, nargs >> 1); | |
235 nargs = 0; | |
236 | |
237 for (rest = gutter; !NILP (rest); rest = XCDR (XCDR (rest))) | |
238 { | |
239 /* We only put things in the real gutter that are declared to be | |
240 visible. */ | |
241 if (!CONSP (WINDOW_GUTTER_VISIBLE (w, pos)) | |
242 || | |
243 !NILP (Fmemq (XCAR (rest), WINDOW_GUTTER_VISIBLE (w, pos)))) | |
244 { | |
245 args [nargs++] = XCAR (XCDR (rest)); | |
246 } | |
247 } | |
248 | |
249 return Fconcat (nargs, args); | |
250 } | |
251 | |
252 static void | |
253 output_gutter (struct frame *f, enum gutter_pos pos, int force) | |
219 { | 254 { |
220 Lisp_Object frame; | 255 Lisp_Object frame; |
221 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | 256 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); |
222 struct device *d = XDEVICE (f->device); | 257 struct device *d = XDEVICE (f->device); |
223 struct window* w = XWINDOW (window); | 258 struct window* w = XWINDOW (window); |
224 int x, y, width, height, ypos; | 259 int x, y, width, height, ypos; |
225 int line, border_width; | 260 int line, border_width; |
226 face_index findex; | 261 face_index findex; |
227 display_line_dynarr* ddla, *cdla; | 262 display_line_dynarr* ddla, *cdla; |
228 struct display_line *dl; | 263 struct display_line *dl = 0; |
229 int cdla_len; | 264 int cdla_len; |
230 | 265 |
231 if (!WINDOW_LIVE_P (w)) | 266 if (!WINDOW_LIVE_P (w)) |
232 return; | 267 return; |
233 | 268 |
234 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos); | 269 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos); |
235 findex = get_builtin_face_cache_index (w, Vgui_element_face); | 270 findex = get_builtin_face_cache_index (w, Vwidget_face); |
236 | 271 |
237 if (!f->current_display_lines) | 272 if (!f->current_display_lines[pos]) |
238 f->current_display_lines = Dynarr_new (display_line); | 273 f->current_display_lines[pos] = Dynarr_new (display_line); |
239 if (!f->desired_display_lines) | 274 if (!f->desired_display_lines[pos]) |
240 f->desired_display_lines = Dynarr_new (display_line); | 275 f->desired_display_lines[pos] = Dynarr_new (display_line); |
241 | 276 |
242 ddla = f->desired_display_lines; | 277 ddla = f->desired_display_lines[pos]; |
243 cdla = f->current_display_lines; | 278 cdla = f->current_display_lines[pos]; |
244 cdla_len = Dynarr_length (cdla); | 279 cdla_len = Dynarr_length (cdla); |
245 | 280 |
246 XSETFRAME (frame, f); | 281 XSETFRAME (frame, f); |
247 | 282 |
248 get_gutter_coords (f, pos, &x, &y, &width, &height); | 283 get_gutter_coords (f, pos, &x, &y, &width, &height); |
249 /* generate some display lines */ | 284 /* generate some display lines */ |
250 generate_displayable_area (w, WINDOW_GUTTER (w, pos), | 285 generate_displayable_area (w, WINDOW_GUTTER (w, pos), |
251 x + border_width, y + border_width, | 286 x + border_width, y + border_width, |
252 width - 2 * border_width, | 287 width - 2 * border_width, |
253 height - 2 * border_width, ddla, 0, findex); | 288 height - 2 * border_width, ddla, 0, findex); |
254 /* Output each line. */ | 289 |
255 for (line = 0; line < Dynarr_length (ddla); line++) | 290 /* We only output the gutter if we think something of significance |
256 { | 291 has changed. This is, for example, because redisplay can cause |
257 output_display_line (w, cdla, ddla, line, -1, -1); | 292 new face cache elements to get added causing compare_runes to |
258 } | 293 fail because the findex for a particular face has changed. */ |
259 | 294 if (force || f->faces_changed || f->frame_changed || |
260 /* If the number of display lines has shrunk, adjust. */ | 295 f->gutter_changed || f->glyphs_changed || |
261 if (cdla_len > Dynarr_length (ddla)) | 296 f->size_changed || f->subwindows_changed || |
262 { | 297 w->windows_changed || f->windows_structure_changed || |
263 Dynarr_length (cdla) = Dynarr_length (ddla); | 298 cdla_len != Dynarr_length (ddla) || |
264 } | 299 (f->extents_changed && w->gutter_extent_modiff[pos])) |
265 | 300 { |
266 /* grab coordinates of last line and blank after it. */ | 301 #ifdef DEBUG_GUTTERS |
267 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); | 302 printf ("gutter redisplay triggered by %s\n", force ? "force" : |
268 ypos = dl->ypos + dl->descent - dl->clip; | 303 f->faces_changed ? "f->faces_changed" : |
269 redisplay_clear_region (window, findex, x + border_width , ypos, | 304 f->frame_changed ? "f->frame_changed" : |
270 width - 2 * border_width, height - (ypos - y) - border_width); | 305 f->gutter_changed ? "f->gutter_changed" : |
271 /* bevel the gutter area if so desired */ | 306 f->glyphs_changed ? "f->glyphs_changed" : |
272 if (border_width != 0) | 307 f->size_changed ? "f->size_changed" : |
273 { | 308 f->subwindows_changed ? "f->subwindows_changed" : |
274 MAYBE_DEVMETH (d, bevel_area, | 309 w->windows_changed ? "w->windows_changed" : |
275 (w, findex, x, y, width, height, border_width, | 310 f->windows_structure_changed ? "f->windows_structure_changed" : |
276 EDGE_ALL, EDGE_BEVEL_OUT)); | 311 cdla_len != Dynarr_length (ddla) ? "different display structures" : |
277 } | 312 f->extents_changed && w->gutter_extent_modiff[pos] ? |
278 } | 313 "f->extents_changed && w->gutter_extent_modiff[pos]" : "<null>"); |
279 | 314 #endif |
280 /* sizing gutters is a pain so we try and help the user by detemining | 315 /* Output each line. */ |
316 for (line = 0; line < Dynarr_length (ddla); line++) | |
317 { | |
318 output_display_line (w, cdla, ddla, line, -1, -1); | |
319 } | |
320 | |
321 /* If the number of display lines has shrunk, adjust. */ | |
322 if (cdla_len > Dynarr_length (ddla)) | |
323 { | |
324 Dynarr_length (cdla) = Dynarr_length (ddla); | |
325 } | |
326 | |
327 /* grab coordinates of last line and blank after it. */ | |
328 if (Dynarr_length (ddla) > 0) | |
329 { | |
330 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); | |
331 ypos = dl->ypos + dl->descent - dl->clip; | |
332 } | |
333 else | |
334 ypos = y; | |
335 | |
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)) | |
343 { | |
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); | |
358 } | |
359 | |
360 /* bevel the gutter area if so desired */ | |
361 if (border_width != 0) | |
362 { | |
363 MAYBE_DEVMETH (d, bevel_area, | |
364 (w, findex, x, y, width, height, border_width, | |
365 EDGE_ALL, EDGE_BEVEL_OUT)); | |
366 } | |
367 } | |
368 else | |
369 { | |
370 /* Nothing of significance happened so sync the display line | |
371 structs. */ | |
372 for (line = 0; line < Dynarr_length (ddla); line++) | |
373 { | |
374 sync_display_line_structs (w, line, 1, cdla, ddla); | |
375 } | |
376 } | |
377 | |
378 w->gutter_extent_modiff [pos] = 0; | |
379 } | |
380 | |
381 /* Sizing gutters is a pain so we try and help the user by determining | |
281 what height will accommodate all lines. This is useless on left and | 382 what height will accommodate all lines. This is useless on left and |
282 right gutters as we always have a maximal number of lines. */ | 383 right gutters as we always have a maximal number of lines. */ |
283 static Lisp_Object | 384 static Lisp_Object |
284 calculate_gutter_size (struct window *w, enum gutter_pos pos) | 385 calculate_gutter_size (struct window *w, enum gutter_pos pos) |
285 { | 386 { |
286 struct frame* f = XFRAME (WINDOW_FRAME (w)); | 387 struct frame* f = XFRAME (WINDOW_FRAME (w)); |
287 int ypos; | 388 int ypos, count; |
288 display_line_dynarr* ddla; | 389 display_line_dynarr* ddla; |
289 struct display_line *dl; | 390 struct display_line *dl; |
290 | 391 |
291 /* we cannot autodetect gutter sizes for the left and right as there | 392 /* we cannot autodetect gutter sizes for the left and right as there |
292 is no reasonable metric to use */ | 393 is no reasonable metric to use */ |
293 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER); | 394 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER); |
294 /* degenerate case */ | 395 /* degenerate case */ |
295 if (NILP (WINDOW_GUTTER (w, pos)) | 396 if (NILP (RAW_WINDOW_GUTTER (w, pos)) |
296 || | 397 || |
297 !FRAME_VISIBLE_P (f) | 398 !FRAME_VISIBLE_P (f) |
298 || | 399 || |
299 NILP (w->buffer)) | 400 NILP (w->buffer)) |
300 return Qnil; | 401 return Qnil; |
402 | |
403 /* Redisplay code that we use relies on GC not happening. Make it | |
404 so. */ | |
405 count = specpdl_depth (); | |
406 record_unwind_protect (restore_gc_inhibit, | |
407 make_int (gc_currently_forbidden)); | |
408 gc_currently_forbidden = 1; | |
301 | 409 |
302 ddla = Dynarr_new (display_line); | 410 ddla = Dynarr_new (display_line); |
303 /* generate some display lines */ | 411 /* generate some display lines */ |
304 generate_displayable_area (w, WINDOW_GUTTER (w, pos), | 412 generate_displayable_area (w, WINDOW_GUTTER (w, pos), |
305 FRAME_LEFT_BORDER_END (f), | 413 FRAME_LEFT_BORDER_END (f), |
306 0, | 414 0, |
307 FRAME_RIGHT_BORDER_START (f) | 415 FRAME_RIGHT_BORDER_START (f) |
308 - FRAME_LEFT_BORDER_END (f), | 416 - FRAME_LEFT_BORDER_END (f), |
309 200, | 417 200, |
310 ddla, 0, 0); | 418 ddla, 0, 0); |
419 | |
420 /* Let GC happen again. */ | |
421 unbind_to (count, Qnil); | |
422 | |
311 /* grab coordinates of last line */ | 423 /* grab coordinates of last line */ |
312 if (Dynarr_length (ddla)) | 424 if (Dynarr_length (ddla)) |
313 { | 425 { |
314 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); | 426 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); |
315 ypos = dl->ypos + dl->descent - dl->clip; | 427 ypos = dl->ypos + dl->descent - dl->clip; |
327 clear_gutter (struct frame *f, enum gutter_pos pos) | 439 clear_gutter (struct frame *f, enum gutter_pos pos) |
328 { | 440 { |
329 int x, y, width, height; | 441 int x, y, width, height; |
330 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | 442 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); |
331 face_index findex = get_builtin_face_cache_index (XWINDOW (window), | 443 face_index findex = get_builtin_face_cache_index (XWINDOW (window), |
332 Vgui_element_face); | 444 Vwidget_face); |
333 get_gutter_coords (f, pos, &x, &y, &width, &height); | 445 get_gutter_coords (f, pos, &x, &y, &width, &height); |
334 | 446 |
335 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0); | 447 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0); |
336 | 448 |
337 redisplay_clear_region (window, findex, x, y, width, height); | 449 redisplay_clear_region (window, findex, x, y, width, height); |
450 } | |
451 | |
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. */ | |
456 | |
457 /* See the comment in image_instantiate_cache_result as to why marking | |
458 the glyph will also mark the image_instance. */ | |
459 void | |
460 mark_gutters (struct frame* f) | |
461 { | |
462 enum gutter_pos pos; | |
463 GUTTER_POS_LOOP (pos) | |
464 { | |
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]); | |
470 } | |
471 } | |
472 | |
473 /* This is called by extent_changed_for_redisplay, so that redisplay | |
474 knows exactly what extents have changed. */ | |
475 void | |
476 gutter_extent_signal_changed_region_maybe (Lisp_Object obj, | |
477 Bufpos start, Bufpos end) | |
478 { | |
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; | |
483 | |
484 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) | |
485 { | |
486 struct frame *f = XFRAME (XCAR (frmcons)); | |
487 enum gutter_pos pos; | |
488 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); | |
489 struct window* w = XWINDOW (window); | |
490 | |
491 GUTTER_POS_LOOP (pos) | |
492 { | |
493 if (EQ (WINDOW_GUTTER (w, pos), obj)) | |
494 { | |
495 w->gutter_extent_modiff[pos]++; | |
496 } | |
497 } | |
498 } | |
499 } | |
500 | |
501 /* We have to change the gutter geometry separately to the gutter | |
502 update since it needs to occur outside of redisplay proper. */ | |
503 static void | |
504 update_gutter_geometry (struct frame *f, enum gutter_pos pos) | |
505 { | |
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]) | |
511 { | |
512 int width, height; | |
513 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f), | |
514 &width, &height); | |
515 change_frame_size (f, height, width, 0); | |
516 } | |
517 | |
518 /* Mark sizes as up-to-date. */ | |
519 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos); | |
520 } | |
521 | |
522 void | |
523 update_frame_gutter_geometry (struct frame *f) | |
524 { | |
525 if (f->gutter_changed || f->windows_structure_changed) | |
526 { | |
527 enum gutter_pos pos; | |
528 | |
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) | |
534 { | |
535 update_gutter_geometry (f, pos); | |
536 } | |
537 } | |
338 } | 538 } |
339 | 539 |
340 void | 540 void |
341 update_frame_gutters (struct frame *f) | 541 update_frame_gutters (struct frame *f) |
342 { | 542 { |
343 if (f->gutter_changed || f->clear || | 543 if (f->faces_changed || f->frame_changed || |
344 f->glyphs_changed || f->subwindows_changed || | 544 f->gutter_changed || f->glyphs_changed || |
345 f->windows_changed || f->windows_structure_changed || | 545 f->size_changed || f->subwindows_changed || |
346 f->extents_changed || f->faces_changed) | 546 f->windows_changed || f->windows_structure_changed || |
547 f->extents_changed) | |
347 { | 548 { |
348 enum gutter_pos pos; | 549 enum gutter_pos pos; |
349 | 550 |
350 /* We don't actually care about these when outputting the gutter | 551 /* We don't actually care about these when outputting the gutter |
351 so locally disable them. */ | 552 so locally disable them. */ |
352 int local_clip_changed = f->clip_changed; | 553 int local_clip_changed = f->clip_changed; |
353 int local_buffers_changed = f->buffers_changed; | 554 int local_buffers_changed = f->buffers_changed; |
354 f->clip_changed = 0; | 555 f->clip_changed = 0; |
356 | 557 |
357 /* and output */ | 558 /* and output */ |
358 GUTTER_POS_LOOP (pos) | 559 GUTTER_POS_LOOP (pos) |
359 { | 560 { |
360 if (FRAME_GUTTER_VISIBLE (f, pos)) | 561 if (FRAME_GUTTER_VISIBLE (f, pos)) |
361 output_gutter (f, pos); | 562 output_gutter (f, pos, 0); |
563 | |
362 else if (gutter_was_visible (f, pos)) | 564 else if (gutter_was_visible (f, pos)) |
363 clear_gutter (f, pos); | 565 clear_gutter (f, pos); |
364 } | 566 } |
567 | |
365 f->clip_changed = local_clip_changed; | 568 f->clip_changed = local_clip_changed; |
366 f->buffers_changed = local_buffers_changed; | 569 f->buffers_changed = local_buffers_changed; |
367 f->gutter_changed = 0; | 570 f->gutter_changed = 0; |
368 } | 571 } |
369 } | 572 } |
370 | 573 |
371 void | 574 void |
372 reset_gutter_display_lines (struct frame* f) | 575 reset_gutter_display_lines (struct frame* f) |
373 { | 576 { |
374 if (f->current_display_lines) | 577 enum gutter_pos pos; |
375 Dynarr_reset (f->current_display_lines); | 578 GUTTER_POS_LOOP (pos) |
579 { | |
580 if (f->current_display_lines[pos]) | |
581 Dynarr_reset (f->current_display_lines[pos]); | |
582 } | |
376 } | 583 } |
377 | 584 |
378 static void | 585 static void |
379 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y, | 586 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y, |
380 int width, int height) | 587 int width, int height) |
386 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width) | 593 if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width) |
387 return; | 594 return; |
388 if (((x + width) < g_x) || (x > (g_x + g_width))) | 595 if (((x + width) < g_x) || (x > (g_x + g_width))) |
389 return; | 596 return; |
390 | 597 |
598 #ifdef DEBUG_WIDGETS | |
599 printf ("redrawing gutter after expose %d+%d, %dx%d\n", | |
600 x, y, width, height); | |
601 #endif | |
391 /* #### optimize this - redrawing the whole gutter for every expose | 602 /* #### optimize this - redrawing the whole gutter for every expose |
392 is very expensive. We reset the current display lines because if | 603 is very expensive. We reset the current display lines because if |
393 they're being exposed they are no longer current. */ | 604 they're being exposed they are no longer current. */ |
394 reset_gutter_display_lines (f); | 605 reset_gutter_display_lines (f); |
395 | 606 |
396 /* Even if none of the gutter is in the area, the blank region at | 607 /* Even if none of the gutter is in the area, the blank region at |
397 the very least must be because the first thing we did is verify | 608 the very least must be because the first thing we did is verify |
398 that some portion of the gutter is in the exposed region. */ | 609 that some portion of the gutter is in the exposed region. */ |
399 output_gutter (f, pos); | 610 output_gutter (f, pos, 1); |
400 } | 611 } |
401 | 612 |
402 void | 613 void |
403 redraw_exposed_gutters (struct frame *f, int x, int y, int width, | 614 redraw_exposed_gutters (struct frame *f, int x, int y, int width, |
404 int height) | 615 int height) |
405 { | 616 { |
406 enum gutter_pos pos; | 617 enum gutter_pos pos; |
618 | |
619 /* We have to be "in display" when we output the gutter - make it | |
620 so. */ | |
621 hold_frame_size_changes (); | |
407 GUTTER_POS_LOOP (pos) | 622 GUTTER_POS_LOOP (pos) |
408 { | 623 { |
409 if (FRAME_GUTTER_VISIBLE (f, pos)) | 624 if (FRAME_GUTTER_VISIBLE (f, pos)) |
410 redraw_exposed_gutter (f, pos, x, y, width, height); | 625 redraw_exposed_gutter (f, pos, x, y, width, height); |
411 } | 626 } |
627 unhold_one_frame_size_changes (f); | |
412 } | 628 } |
413 | 629 |
414 void | 630 void |
415 free_frame_gutters (struct frame *f) | 631 free_frame_gutters (struct frame *f) |
416 { | 632 { |
417 if (f->current_display_lines) | 633 enum gutter_pos pos; |
418 { | 634 GUTTER_POS_LOOP (pos) |
419 free_display_lines (f->current_display_lines); | 635 { |
420 f->current_display_lines = 0; | 636 if (f->current_display_lines[pos]) |
421 } | 637 { |
422 if (f->desired_display_lines) | 638 free_display_lines (f->current_display_lines[pos]); |
423 { | 639 f->current_display_lines[pos] = 0; |
424 free_display_lines (f->desired_display_lines); | 640 } |
425 f->desired_display_lines = 0; | 641 if (f->desired_display_lines[pos]) |
642 { | |
643 free_display_lines (f->desired_display_lines[pos]); | |
644 f->desired_display_lines[pos] = 0; | |
645 } | |
426 } | 646 } |
427 } | 647 } |
428 | 648 |
429 static enum gutter_pos | 649 static enum gutter_pos |
430 decode_gutter_position (Lisp_Object position) | 650 decode_gutter_position (Lisp_Object position) |
464 : Vdefault_gutter_width); | 684 : Vdefault_gutter_width); |
465 set_specifier_fallback (Vgutter_border_width[cur], | 685 set_specifier_fallback (Vgutter_border_width[cur], |
466 list1 (Fcons (Qnil, Qzero))); | 686 list1 (Fcons (Qnil, Qzero))); |
467 set_specifier_fallback (Vgutter_border_width[new], | 687 set_specifier_fallback (Vgutter_border_width[new], |
468 Vdefault_gutter_border_width); | 688 Vdefault_gutter_border_width); |
689 /* We don't really want the left and right gutters to default to | |
690 visible. */ | |
469 set_specifier_fallback (Vgutter_visible_p[cur], | 691 set_specifier_fallback (Vgutter_visible_p[cur], |
470 list1 (Fcons (Qnil, Qt))); | 692 cur == TOP_GUTTER || cur == BOTTOM_GUTTER ? |
693 list1 (Fcons (Qnil, Qt)) | |
694 : list1 (Fcons (Qnil, Qnil))); | |
471 set_specifier_fallback (Vgutter_visible_p[new], | 695 set_specifier_fallback (Vgutter_visible_p[new], |
472 Vdefault_gutter_visible_p); | 696 Vdefault_gutter_visible_p); |
697 | |
473 Vdefault_gutter_position = position; | 698 Vdefault_gutter_position = position; |
474 unhold_frame_size_changes (); | 699 unhold_frame_size_changes (); |
475 } | 700 } |
701 | |
702 run_hook (Qdefault_gutter_position_changed_hook); | |
476 | 703 |
477 return position; | 704 return position; |
478 } | 705 } |
479 | 706 |
480 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /* | 707 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /* |
541 gutter_validate (Lisp_Object instantiator) | 768 gutter_validate (Lisp_Object instantiator) |
542 { | 769 { |
543 if (NILP (instantiator)) | 770 if (NILP (instantiator)) |
544 return; | 771 return; |
545 | 772 |
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); | |
776 | |
546 if (!STRINGP (instantiator)) | 777 if (!STRINGP (instantiator)) |
547 signal_simple_error ("Gutter spec must be string or nil", instantiator); | 778 { |
779 Lisp_Object rest; | |
780 | |
781 for (rest = instantiator; !NILP (rest); rest = XCDR (XCDR (rest))) | |
782 { | |
783 if (!SYMBOLP (XCAR (rest)) | |
784 || !STRINGP (XCAR (XCDR (rest)))) | |
785 signal_simple_error ("Gutter plist spec must contain strings", instantiator); | |
786 } | |
787 } | |
548 } | 788 } |
549 | 789 |
550 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /* | 790 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /* |
551 Return non-nil if OBJECT is a gutter specifier. | 791 Return non-nil if OBJECT is a gutter specifier. |
552 Gutter specifiers are used to specify the format of a gutter. | 792 |
553 The values of the variables `default-gutter', `top-gutter', | 793 See `make-gutter-specifier' for a description of possible gutter |
554 `left-gutter', `right-gutter', and `bottom-gutter' are always | 794 instantiators. |
555 gutter specifiers. | |
556 | |
557 Valid gutter instantiators are called "gutter descriptors" | |
558 and are lists of vectors. See `default-gutter' for a description | |
559 of the exact format. | |
560 */ | 795 */ |
561 (object)) | 796 (object)) |
562 { | 797 { |
563 return GUTTER_SPECIFIERP (object) ? Qt : Qnil; | 798 return GUTTER_SPECIFIERP (object) ? Qt : Qnil; |
564 } | 799 } |
575 Fset_specifier_dirty_flag (real_one[pos]); | 810 Fset_specifier_dirty_flag (real_one[pos]); |
576 } | 811 } |
577 | 812 |
578 static void | 813 static void |
579 gutter_specs_changed (Lisp_Object specifier, struct window *w, | 814 gutter_specs_changed (Lisp_Object specifier, struct window *w, |
580 Lisp_Object oldval) | 815 Lisp_Object oldval, enum gutter_pos pos) |
816 { | |
817 w->real_gutter[pos] = construct_window_gutter_spec (w, pos); | |
818 w->real_gutter_size[pos] = w->gutter_size[pos]; | |
819 | |
820 if (EQ (w->real_gutter_size[pos], Qautodetect) | |
821 && !NILP (w->gutter_visible_p[pos])) | |
822 { | |
823 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | |
824 } | |
825 MARK_GUTTER_CHANGED; | |
826 MARK_MODELINE_CHANGED; | |
827 MARK_WINDOWS_CHANGED (w); | |
828 } | |
829 | |
830 /* We define all of these so we can access which actual gutter changed. */ | |
831 static void | |
832 top_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
833 Lisp_Object oldval) | |
834 { | |
835 gutter_specs_changed (specifier, w, oldval, TOP_GUTTER); | |
836 } | |
837 | |
838 static void | |
839 bottom_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
840 Lisp_Object oldval) | |
841 { | |
842 gutter_specs_changed (specifier, w, oldval, BOTTOM_GUTTER); | |
843 } | |
844 | |
845 static void | |
846 left_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
847 Lisp_Object oldval) | |
848 { | |
849 gutter_specs_changed (specifier, w, oldval, LEFT_GUTTER); | |
850 } | |
851 | |
852 static void | |
853 right_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
854 Lisp_Object oldval) | |
855 { | |
856 gutter_specs_changed (specifier, w, oldval, RIGHT_GUTTER); | |
857 } | |
858 | |
859 static void | |
860 default_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
861 Lisp_Object oldval) | |
862 { | |
863 recompute_overlaying_specifier (Vgutter); | |
864 } | |
865 | |
866 static void | |
867 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w, | |
868 Lisp_Object oldval) | |
581 { | 869 { |
582 enum gutter_pos pos; | 870 enum gutter_pos pos; |
583 GUTTER_POS_LOOP (pos) | 871 GUTTER_POS_LOOP (pos) |
584 { | 872 { |
585 w->real_gutter_size[pos] = w->gutter_size[pos]; | 873 w->real_gutter_size[pos] = w->gutter_size[pos]; |
587 && !NILP (w->gutter_visible_p[pos])) | 875 && !NILP (w->gutter_visible_p[pos])) |
588 { | 876 { |
589 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | 877 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); |
590 } | 878 } |
591 } | 879 } |
880 | |
592 MARK_GUTTER_CHANGED; | 881 MARK_GUTTER_CHANGED; |
593 MARK_WINDOWS_CHANGED (w); | 882 MARK_MODELINE_CHANGED; |
594 } | |
595 | |
596 static void | |
597 default_gutter_specs_changed (Lisp_Object specifier, struct window *w, | |
598 Lisp_Object oldval) | |
599 { | |
600 recompute_overlaying_specifier (Vgutter); | |
601 } | |
602 | |
603 static void | |
604 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w, | |
605 Lisp_Object oldval) | |
606 { | |
607 enum gutter_pos pos; | |
608 GUTTER_POS_LOOP (pos) | |
609 { | |
610 w->real_gutter_size[pos] = w->gutter_size[pos]; | |
611 if (EQ (w->real_gutter_size[pos], Qautodetect) | |
612 && !NILP (w->gutter_visible_p[pos])) | |
613 { | |
614 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | |
615 } | |
616 } | |
617 | |
618 MARK_GUTTER_CHANGED; | |
619 MARK_WINDOWS_CHANGED (w); | 883 MARK_WINDOWS_CHANGED (w); |
620 } | 884 } |
621 | 885 |
622 static void | 886 static void |
623 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w, | 887 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w, |
638 default_gutter_visible_p_changed_in_window (Lisp_Object specifier, | 902 default_gutter_visible_p_changed_in_window (Lisp_Object specifier, |
639 struct window *w, | 903 struct window *w, |
640 Lisp_Object oldval) | 904 Lisp_Object oldval) |
641 { | 905 { |
642 recompute_overlaying_specifier (Vgutter_visible_p); | 906 recompute_overlaying_specifier (Vgutter_visible_p); |
907 /* Need to reconstruct the gutter specifier as it is affected by the | |
908 visibility. */ | |
909 recompute_overlaying_specifier (Vgutter); | |
643 } | 910 } |
644 | 911 |
645 | 912 |
646 DECLARE_SPECIFIER_TYPE (gutter_size); | 913 DECLARE_SPECIFIER_TYPE (gutter_size); |
647 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size) | 914 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size) |
657 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator); | 924 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator); |
658 } | 925 } |
659 | 926 |
660 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /* | 927 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /* |
661 Return non-nil if OBJECT is a gutter-size specifier. | 928 Return non-nil if OBJECT is a gutter-size specifier. |
929 | |
930 See `make-gutter-size-specifier' for a description of possible gutter-size | |
931 instantiators. | |
662 */ | 932 */ |
663 (object)) | 933 (object)) |
664 { | 934 { |
665 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil; | 935 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil; |
936 } | |
937 | |
938 DECLARE_SPECIFIER_TYPE (gutter_visible); | |
939 #define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible) | |
940 DEFINE_SPECIFIER_TYPE (gutter_visible); | |
941 | |
942 static void | |
943 gutter_visible_validate (Lisp_Object instantiator) | |
944 { | |
945 if (NILP (instantiator)) | |
946 return; | |
947 | |
948 if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator)) | |
949 signal_simple_error ("Gutter visibility must be a boolean or list of symbols", | |
950 instantiator); | |
951 | |
952 if (CONSP (instantiator)) | |
953 { | |
954 Lisp_Object rest; | |
955 | |
956 EXTERNAL_LIST_LOOP (rest, instantiator) | |
957 { | |
958 if (!SYMBOLP (XCAR (rest))) | |
959 signal_simple_error ("Gutter visibility must be a boolean or list of symbols", | |
960 instantiator); | |
961 } | |
962 } | |
963 } | |
964 | |
965 DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /* | |
966 Return non-nil if OBJECT is a gutter-visible specifier. | |
967 | |
968 See `make-gutter-visible-specifier' for a description of possible | |
969 gutter-visible instantiators. | |
970 */ | |
971 (object)) | |
972 { | |
973 return GUTTER_VISIBLE_SPECIFIERP (object) ? Qt : Qnil; | |
666 } | 974 } |
667 | 975 |
668 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /* | 976 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /* |
669 Ensure that all gutters are correctly showing their gutter specifier. | 977 Ensure that all gutters are correctly showing their gutter specifier. |
670 */ | 978 */ |
679 | 987 |
680 DEVICE_FRAME_LOOP (frmcons, d) | 988 DEVICE_FRAME_LOOP (frmcons, d) |
681 { | 989 { |
682 struct frame *f = XFRAME (XCAR (frmcons)); | 990 struct frame *f = XFRAME (XCAR (frmcons)); |
683 | 991 |
684 if (FRAME_REPAINT_P (f)) | 992 MAYBE_DEVMETH (d, frame_output_begin, (f)); |
993 | |
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. | |
998 | |
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 | |
1006 size changes. */ | |
1007 update_frame_gutter_geometry (f); | |
1008 | |
1009 if (f->windows_structure_changed) | |
1010 redisplay_frame (f, 1); | |
1011 else if (FRAME_REPAINT_P (f)) | |
685 { | 1012 { |
1013 /* We have to be "in display" when we output the gutter | |
1014 - make it so. */ | |
1015 hold_frame_size_changes (); | |
686 update_frame_gutters (f); | 1016 update_frame_gutters (f); |
1017 unhold_one_frame_size_changes (f); | |
687 } | 1018 } |
688 } | 1019 |
689 | 1020 MAYBE_DEVMETH (d, frame_output_end, (f)); |
690 /* We now call the output_end routine for tty frames. We delay | 1021 } |
691 doing so in order to avoid cursor flicker. So much for 100% | 1022 |
692 encapsulation. */ | 1023 d->gutter_changed = 0; |
693 if (DEVICE_TTY_P (d)) | 1024 } |
694 DEVMETH (d, output_end, (d)); | 1025 |
695 } | 1026 /* This is so that further changes to the gutters will trigger redisplay. */ |
1027 gutter_changed_set = 0; | |
1028 gutter_changed = 0; | |
696 | 1029 |
697 return Qnil; | 1030 return Qnil; |
698 } | 1031 } |
699 | 1032 |
700 void | 1033 void |
705 /* We are here as far in frame creation so cached specifiers are | 1038 /* We are here as far in frame creation so cached specifiers are |
706 already recomputed, and possibly modified by resource | 1039 already recomputed, and possibly modified by resource |
707 initialization. We need to recalculate autodetected gutters. */ | 1040 initialization. We need to recalculate autodetected gutters. */ |
708 GUTTER_POS_LOOP (pos) | 1041 GUTTER_POS_LOOP (pos) |
709 { | 1042 { |
1043 w->real_gutter[pos] = construct_window_gutter_spec (w, pos); | |
710 w->real_gutter_size[pos] = w->gutter_size[pos]; | 1044 w->real_gutter_size[pos] = w->gutter_size[pos]; |
711 if (EQ (w->gutter_size[pos], Qautodetect) | 1045 if (EQ (w->gutter_size[pos], Qautodetect) |
712 && !NILP (w->gutter_visible_p[pos])) | 1046 && !NILP (w->gutter_visible_p[pos])) |
713 { | 1047 { |
714 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); | 1048 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); |
715 MARK_GUTTER_CHANGED; | 1049 MARK_GUTTER_CHANGED; |
716 MARK_WINDOWS_CHANGED (w); | 1050 MARK_WINDOWS_CHANGED (w); |
717 } | 1051 } |
718 } | 1052 } |
1053 | |
1054 /* Keep a record of the current sizes of things. */ | |
1055 GUTTER_POS_LOOP (pos) | |
1056 { | |
1057 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos); | |
1058 } | |
719 } | 1059 } |
720 | 1060 |
721 void | 1061 void |
722 syms_of_gutter (void) | 1062 syms_of_gutter (void) |
723 { | 1063 { |
724 DEFSUBR (Fgutter_specifier_p); | 1064 DEFSUBR (Fgutter_specifier_p); |
725 DEFSUBR (Fgutter_size_specifier_p); | 1065 DEFSUBR (Fgutter_size_specifier_p); |
1066 DEFSUBR (Fgutter_visible_specifier_p); | |
726 DEFSUBR (Fset_default_gutter_position); | 1067 DEFSUBR (Fset_default_gutter_position); |
727 DEFSUBR (Fdefault_gutter_position); | 1068 DEFSUBR (Fdefault_gutter_position); |
728 DEFSUBR (Fgutter_pixel_height); | 1069 DEFSUBR (Fgutter_pixel_height); |
729 DEFSUBR (Fgutter_pixel_width); | 1070 DEFSUBR (Fgutter_pixel_width); |
730 DEFSUBR (Fredisplay_gutter_area); | 1071 DEFSUBR (Fredisplay_gutter_area); |
731 | 1072 |
732 defsymbol (&Qgutter_size, "gutter-size"); | 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"); | |
733 } | 1077 } |
734 | 1078 |
735 void | 1079 void |
736 vars_of_gutter (void) | 1080 vars_of_gutter (void) |
737 { | 1081 { |
743 | 1087 |
744 void | 1088 void |
745 specifier_type_create_gutter (void) | 1089 specifier_type_create_gutter (void) |
746 { | 1090 { |
747 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p"); | 1091 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p"); |
748 | |
749 SPECIFIER_HAS_METHOD (gutter, validate); | 1092 SPECIFIER_HAS_METHOD (gutter, validate); |
750 SPECIFIER_HAS_METHOD (gutter, after_change); | 1093 SPECIFIER_HAS_METHOD (gutter, after_change); |
751 | 1094 |
752 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p"); | 1095 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p"); |
753 | |
754 SPECIFIER_HAS_METHOD (gutter_size, validate); | 1096 SPECIFIER_HAS_METHOD (gutter_size, validate); |
1097 | |
1098 INITIALIZE_SPECIFIER_TYPE (gutter_visible, "gutter-visible", "gutter-visible-specifier-p"); | |
1099 SPECIFIER_HAS_METHOD (gutter_visible, validate); | |
755 } | 1100 } |
756 | 1101 |
757 void | 1102 void |
758 reinit_specifier_type_create_gutter (void) | 1103 reinit_specifier_type_create_gutter (void) |
759 { | 1104 { |
760 REINITIALIZE_SPECIFIER_TYPE (gutter); | 1105 REINITIALIZE_SPECIFIER_TYPE (gutter); |
761 REINITIALIZE_SPECIFIER_TYPE (gutter_size); | 1106 REINITIALIZE_SPECIFIER_TYPE (gutter_size); |
1107 REINITIALIZE_SPECIFIER_TYPE (gutter_visible); | |
762 } | 1108 } |
763 | 1109 |
764 void | 1110 void |
765 specifier_vars_of_gutter (void) | 1111 specifier_vars_of_gutter (void) |
766 { | 1112 { |
797 the visibility and thickness using `default-gutter-visible-p', | 1143 the visibility and thickness using `default-gutter-visible-p', |
798 `default-gutter-width', and `default-gutter-height', rather than | 1144 `default-gutter-width', and `default-gutter-height', rather than |
799 using position-specific specifiers. That way, you will get sane | 1145 using position-specific specifiers. That way, you will get sane |
800 behavior if the user changes the default gutter position. | 1146 behavior if the user changes the default gutter position. |
801 | 1147 |
802 The gutter value should be a string or nil. You can attach extents and | 1148 The gutter value should be a string, a property list of strings or |
803 glyphs to the string and hence display glyphs and text in other fonts | 1149 nil. You can attach extents and glyphs to the string and hence display |
804 in the gutter area. | 1150 glyphs and text in other fonts in the gutter area. If the gutter value |
805 | 1151 is a property list then the strings will be concatenated together |
806 */ ); | 1152 before being displayed. */ ); |
807 | 1153 |
808 Vdefault_gutter = Fmake_specifier (Qgutter); | 1154 Vdefault_gutter = Fmake_specifier (Qgutter); |
809 /* #### It would be even nicer if the specifier caching | 1155 /* #### It would be even nicer if the specifier caching |
810 automatically knew about specifier fallbacks, so we didn't | 1156 automatically knew about specifier fallbacks, so we didn't |
811 have to do it ourselves. */ | 1157 have to do it ourselves. */ |
821 See `default-gutter' for a description of a valid gutter instantiator. | 1167 See `default-gutter' for a description of a valid gutter instantiator. |
822 */ ); | 1168 */ ); |
823 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter); | 1169 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter); |
824 set_specifier_caching (Vgutter[TOP_GUTTER], | 1170 set_specifier_caching (Vgutter[TOP_GUTTER], |
825 offsetof (struct window, gutter[TOP_GUTTER]), | 1171 offsetof (struct window, gutter[TOP_GUTTER]), |
826 gutter_specs_changed, | 1172 top_gutter_specs_changed, |
827 0, 0); | 1173 0, 0); |
828 | 1174 |
829 DEFVAR_SPECIFIER ("bottom-gutter", | 1175 DEFVAR_SPECIFIER ("bottom-gutter", |
830 &Vgutter[BOTTOM_GUTTER] /* | 1176 &Vgutter[BOTTOM_GUTTER] /* |
831 Specifier for the gutter at the bottom of the frame. | 1177 Specifier for the gutter at the bottom of the frame. |
838 displayed even if you provide a value for `bottom-gutter'. | 1184 displayed even if you provide a value for `bottom-gutter'. |
839 */ ); | 1185 */ ); |
840 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter); | 1186 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter); |
841 set_specifier_caching (Vgutter[BOTTOM_GUTTER], | 1187 set_specifier_caching (Vgutter[BOTTOM_GUTTER], |
842 offsetof (struct window, gutter[BOTTOM_GUTTER]), | 1188 offsetof (struct window, gutter[BOTTOM_GUTTER]), |
843 gutter_specs_changed, | 1189 bottom_gutter_specs_changed, |
844 0, 0); | 1190 0, 0); |
845 | 1191 |
846 DEFVAR_SPECIFIER ("left-gutter", | 1192 DEFVAR_SPECIFIER ("left-gutter", |
847 &Vgutter[LEFT_GUTTER] /* | 1193 &Vgutter[LEFT_GUTTER] /* |
848 Specifier for the gutter at the left edge of the frame. | 1194 Specifier for the gutter at the left edge of the frame. |
855 displayed even if you provide a value for `left-gutter'. | 1201 displayed even if you provide a value for `left-gutter'. |
856 */ ); | 1202 */ ); |
857 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter); | 1203 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter); |
858 set_specifier_caching (Vgutter[LEFT_GUTTER], | 1204 set_specifier_caching (Vgutter[LEFT_GUTTER], |
859 offsetof (struct window, gutter[LEFT_GUTTER]), | 1205 offsetof (struct window, gutter[LEFT_GUTTER]), |
860 gutter_specs_changed, | 1206 left_gutter_specs_changed, |
861 0, 0); | 1207 0, 0); |
862 | 1208 |
863 DEFVAR_SPECIFIER ("right-gutter", | 1209 DEFVAR_SPECIFIER ("right-gutter", |
864 &Vgutter[RIGHT_GUTTER] /* | 1210 &Vgutter[RIGHT_GUTTER] /* |
865 Specifier for the gutter at the right edge of the frame. | 1211 Specifier for the gutter at the right edge of the frame. |
872 displayed even if you provide a value for `right-gutter'. | 1218 displayed even if you provide a value for `right-gutter'. |
873 */ ); | 1219 */ ); |
874 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter); | 1220 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter); |
875 set_specifier_caching (Vgutter[RIGHT_GUTTER], | 1221 set_specifier_caching (Vgutter[RIGHT_GUTTER], |
876 offsetof (struct window, gutter[RIGHT_GUTTER]), | 1222 offsetof (struct window, gutter[RIGHT_GUTTER]), |
877 gutter_specs_changed, | 1223 right_gutter_specs_changed, |
878 0, 0); | 1224 0, 0); |
879 | 1225 |
880 /* initially, top inherits from default; this can be | 1226 /* initially, top inherits from default; this can be |
881 changed with `set-default-gutter-position'. */ | 1227 changed with `set-default-gutter-position'. */ |
882 fb = list1 (Fcons (Qnil, Qnil)); | 1228 fb = list1 (Fcons (Qnil, Qnil)); |
937 See `default-gutter-height' for more information. | 1283 See `default-gutter-height' for more information. |
938 */ ); | 1284 */ ); |
939 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size); | 1285 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size); |
940 set_specifier_caching (Vgutter_size[TOP_GUTTER], | 1286 set_specifier_caching (Vgutter_size[TOP_GUTTER], |
941 offsetof (struct window, gutter_size[TOP_GUTTER]), | 1287 offsetof (struct window, gutter_size[TOP_GUTTER]), |
942 gutter_geometry_changed_in_window, | 1288 gutter_geometry_changed_in_window, 0, 0); |
943 0, 0); | |
944 | 1289 |
945 DEFVAR_SPECIFIER ("bottom-gutter-height", | 1290 DEFVAR_SPECIFIER ("bottom-gutter-height", |
946 &Vgutter_size[BOTTOM_GUTTER] /* | 1291 &Vgutter_size[BOTTOM_GUTTER] /* |
947 *Height of the bottom gutter. | 1292 *Height of the bottom gutter. |
948 This is a specifier; use `set-specifier' to change it. | 1293 This is a specifier; use `set-specifier' to change it. |
950 See `default-gutter-height' for more information. | 1295 See `default-gutter-height' for more information. |
951 */ ); | 1296 */ ); |
952 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size); | 1297 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size); |
953 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER], | 1298 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER], |
954 offsetof (struct window, gutter_size[BOTTOM_GUTTER]), | 1299 offsetof (struct window, gutter_size[BOTTOM_GUTTER]), |
955 gutter_geometry_changed_in_window, | 1300 gutter_geometry_changed_in_window, 0, 0); |
956 0, 0); | |
957 | 1301 |
958 DEFVAR_SPECIFIER ("left-gutter-width", | 1302 DEFVAR_SPECIFIER ("left-gutter-width", |
959 &Vgutter_size[LEFT_GUTTER] /* | 1303 &Vgutter_size[LEFT_GUTTER] /* |
960 *Width of left gutter. | 1304 *Width of left gutter. |
961 This is a specifier; use `set-specifier' to change it. | 1305 This is a specifier; use `set-specifier' to change it. |
963 See `default-gutter-height' for more information. | 1307 See `default-gutter-height' for more information. |
964 */ ); | 1308 */ ); |
965 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum); | 1309 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum); |
966 set_specifier_caching (Vgutter_size[LEFT_GUTTER], | 1310 set_specifier_caching (Vgutter_size[LEFT_GUTTER], |
967 offsetof (struct window, gutter_size[LEFT_GUTTER]), | 1311 offsetof (struct window, gutter_size[LEFT_GUTTER]), |
968 gutter_geometry_changed_in_window, | 1312 gutter_geometry_changed_in_window, 0, 0); |
969 0, 0); | |
970 | 1313 |
971 DEFVAR_SPECIFIER ("right-gutter-width", | 1314 DEFVAR_SPECIFIER ("right-gutter-width", |
972 &Vgutter_size[RIGHT_GUTTER] /* | 1315 &Vgutter_size[RIGHT_GUTTER] /* |
973 *Width of right gutter. | 1316 *Width of right gutter. |
974 This is a specifier; use `set-specifier' to change it. | 1317 This is a specifier; use `set-specifier' to change it. |
976 See `default-gutter-height' for more information. | 1319 See `default-gutter-height' for more information. |
977 */ ); | 1320 */ ); |
978 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); | 1321 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); |
979 set_specifier_caching (Vgutter_size[RIGHT_GUTTER], | 1322 set_specifier_caching (Vgutter_size[RIGHT_GUTTER], |
980 offsetof (struct window, gutter_size[RIGHT_GUTTER]), | 1323 offsetof (struct window, gutter_size[RIGHT_GUTTER]), |
981 gutter_geometry_changed_in_window, | 1324 gutter_geometry_changed_in_window, 0, 0); |
982 0, 0); | |
983 | 1325 |
984 fb = Qnil; | 1326 fb = Qnil; |
985 #ifdef HAVE_TTY | 1327 #ifdef HAVE_TTY |
986 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb); | 1328 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb); |
987 #endif | 1329 #endif |
1002 #ifdef HAVE_X_WINDOWS | 1344 #ifdef HAVE_X_WINDOWS |
1003 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb); | 1345 fb = Fcons (Fcons (list1 (Qx), make_int (DEFAULT_GUTTER_WIDTH)), fb); |
1004 #endif | 1346 #endif |
1005 #ifdef HAVE_MS_WINDOWS | 1347 #ifdef HAVE_MS_WINDOWS |
1006 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb); | 1348 fb = Fcons (Fcons (list1 (Qmsprinter), Qzero), fb); |
1007 fb = Fcons (Fcons (list1 (Qmswindows), | 1349 fb = Fcons (Fcons (list1 (Qmswindows), |
1008 make_int (DEFAULT_GUTTER_WIDTH)), fb); | 1350 make_int (DEFAULT_GUTTER_WIDTH)), fb); |
1009 #endif | 1351 #endif |
1010 if (!NILP (fb)) | 1352 if (!NILP (fb)) |
1011 set_specifier_fallback (Vdefault_gutter_width, fb); | 1353 set_specifier_fallback (Vdefault_gutter_width, fb); |
1012 | 1354 |
1045 */ ); | 1387 */ ); |
1046 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum); | 1388 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum); |
1047 set_specifier_caching (Vgutter_border_width[TOP_GUTTER], | 1389 set_specifier_caching (Vgutter_border_width[TOP_GUTTER], |
1048 offsetof (struct window, | 1390 offsetof (struct window, |
1049 gutter_border_width[TOP_GUTTER]), | 1391 gutter_border_width[TOP_GUTTER]), |
1050 gutter_geometry_changed_in_window, | 1392 gutter_geometry_changed_in_window, 0, 0); |
1051 0, 0); | |
1052 | 1393 |
1053 DEFVAR_SPECIFIER ("bottom-gutter-border-width", | 1394 DEFVAR_SPECIFIER ("bottom-gutter-border-width", |
1054 &Vgutter_border_width[BOTTOM_GUTTER] /* | 1395 &Vgutter_border_width[BOTTOM_GUTTER] /* |
1055 *Border width of the bottom gutter. | 1396 *Border width of the bottom gutter. |
1056 This is a specifier; use `set-specifier' to change it. | 1397 This is a specifier; use `set-specifier' to change it. |
1059 */ ); | 1400 */ ); |
1060 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum); | 1401 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum); |
1061 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER], | 1402 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER], |
1062 offsetof (struct window, | 1403 offsetof (struct window, |
1063 gutter_border_width[BOTTOM_GUTTER]), | 1404 gutter_border_width[BOTTOM_GUTTER]), |
1064 gutter_geometry_changed_in_window, | 1405 gutter_geometry_changed_in_window, 0, 0); |
1065 0, 0); | |
1066 | 1406 |
1067 DEFVAR_SPECIFIER ("left-gutter-border-width", | 1407 DEFVAR_SPECIFIER ("left-gutter-border-width", |
1068 &Vgutter_border_width[LEFT_GUTTER] /* | 1408 &Vgutter_border_width[LEFT_GUTTER] /* |
1069 *Border width of left gutter. | 1409 *Border width of left gutter. |
1070 This is a specifier; use `set-specifier' to change it. | 1410 This is a specifier; use `set-specifier' to change it. |
1073 */ ); | 1413 */ ); |
1074 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum); | 1414 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum); |
1075 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER], | 1415 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER], |
1076 offsetof (struct window, | 1416 offsetof (struct window, |
1077 gutter_border_width[LEFT_GUTTER]), | 1417 gutter_border_width[LEFT_GUTTER]), |
1078 gutter_geometry_changed_in_window, | 1418 gutter_geometry_changed_in_window, 0, 0); |
1079 0, 0); | |
1080 | 1419 |
1081 DEFVAR_SPECIFIER ("right-gutter-border-width", | 1420 DEFVAR_SPECIFIER ("right-gutter-border-width", |
1082 &Vgutter_border_width[RIGHT_GUTTER] /* | 1421 &Vgutter_border_width[RIGHT_GUTTER] /* |
1083 *Border width of right gutter. | 1422 *Border width of right gutter. |
1084 This is a specifier; use `set-specifier' to change it. | 1423 This is a specifier; use `set-specifier' to change it. |
1087 */ ); | 1426 */ ); |
1088 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); | 1427 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); |
1089 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER], | 1428 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER], |
1090 offsetof (struct window, | 1429 offsetof (struct window, |
1091 gutter_border_width[RIGHT_GUTTER]), | 1430 gutter_border_width[RIGHT_GUTTER]), |
1092 gutter_geometry_changed_in_window, | 1431 gutter_geometry_changed_in_window, 0, 0); |
1093 0, 0); | |
1094 | 1432 |
1095 fb = Qnil; | 1433 fb = Qnil; |
1096 #ifdef HAVE_TTY | 1434 #ifdef HAVE_TTY |
1097 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); | 1435 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); |
1098 #endif | 1436 #endif |
1125 instead. | 1463 instead. |
1126 | 1464 |
1127 `default-gutter-visible-p' and all of the position-specific gutter | 1465 `default-gutter-visible-p' and all of the position-specific gutter |
1128 visibility specifiers have a fallback value of true. | 1466 visibility specifiers have a fallback value of true. |
1129 */ ); | 1467 */ ); |
1130 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean); | 1468 Vdefault_gutter_visible_p = Fmake_specifier (Qgutter_visible); |
1131 set_specifier_caching (Vdefault_gutter_visible_p, | 1469 set_specifier_caching (Vdefault_gutter_visible_p, |
1132 offsetof (struct window, | 1470 offsetof (struct window, |
1133 default_gutter_visible_p), | 1471 default_gutter_visible_p), |
1134 default_gutter_visible_p_changed_in_window, | 1472 default_gutter_visible_p_changed_in_window, |
1135 0, 0); | 1473 0, 0); |
1139 *Whether the top gutter is visible. | 1477 *Whether the top gutter is visible. |
1140 This is a specifier; use `set-specifier' to change it. | 1478 This is a specifier; use `set-specifier' to change it. |
1141 | 1479 |
1142 See `default-gutter-visible-p' for more information. | 1480 See `default-gutter-visible-p' for more information. |
1143 */ ); | 1481 */ ); |
1144 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean); | 1482 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qgutter_visible); |
1145 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER], | 1483 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER], |
1146 offsetof (struct window, | 1484 offsetof (struct window, |
1147 gutter_visible_p[TOP_GUTTER]), | 1485 gutter_visible_p[TOP_GUTTER]), |
1148 gutter_geometry_changed_in_window, | 1486 top_gutter_specs_changed, 0, 0); |
1149 0, 0); | |
1150 | 1487 |
1151 DEFVAR_SPECIFIER ("bottom-gutter-visible-p", | 1488 DEFVAR_SPECIFIER ("bottom-gutter-visible-p", |
1152 &Vgutter_visible_p[BOTTOM_GUTTER] /* | 1489 &Vgutter_visible_p[BOTTOM_GUTTER] /* |
1153 *Whether the bottom gutter is visible. | 1490 *Whether the bottom gutter is visible. |
1154 This is a specifier; use `set-specifier' to change it. | 1491 This is a specifier; use `set-specifier' to change it. |
1155 | 1492 |
1156 See `default-gutter-visible-p' for more information. | 1493 See `default-gutter-visible-p' for more information. |
1157 */ ); | 1494 */ ); |
1158 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean); | 1495 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_visible); |
1159 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER], | 1496 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER], |
1160 offsetof (struct window, | 1497 offsetof (struct window, |
1161 gutter_visible_p[BOTTOM_GUTTER]), | 1498 gutter_visible_p[BOTTOM_GUTTER]), |
1162 gutter_geometry_changed_in_window, | 1499 bottom_gutter_specs_changed, 0, 0); |
1163 0, 0); | |
1164 | 1500 |
1165 DEFVAR_SPECIFIER ("left-gutter-visible-p", | 1501 DEFVAR_SPECIFIER ("left-gutter-visible-p", |
1166 &Vgutter_visible_p[LEFT_GUTTER] /* | 1502 &Vgutter_visible_p[LEFT_GUTTER] /* |
1167 *Whether the left gutter is visible. | 1503 *Whether the left gutter is visible. |
1168 This is a specifier; use `set-specifier' to change it. | 1504 This is a specifier; use `set-specifier' to change it. |
1169 | 1505 |
1170 See `default-gutter-visible-p' for more information. | 1506 See `default-gutter-visible-p' for more information. |
1171 */ ); | 1507 */ ); |
1172 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean); | 1508 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qgutter_visible); |
1173 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER], | 1509 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER], |
1174 offsetof (struct window, | 1510 offsetof (struct window, |
1175 gutter_visible_p[LEFT_GUTTER]), | 1511 gutter_visible_p[LEFT_GUTTER]), |
1176 gutter_geometry_changed_in_window, | 1512 left_gutter_specs_changed, 0, 0); |
1177 0, 0); | |
1178 | 1513 |
1179 DEFVAR_SPECIFIER ("right-gutter-visible-p", | 1514 DEFVAR_SPECIFIER ("right-gutter-visible-p", |
1180 &Vgutter_visible_p[RIGHT_GUTTER] /* | 1515 &Vgutter_visible_p[RIGHT_GUTTER] /* |
1181 *Whether the right gutter is visible. | 1516 *Whether the right gutter is visible. |
1182 This is a specifier; use `set-specifier' to change it. | 1517 This is a specifier; use `set-specifier' to change it. |
1183 | 1518 |
1184 See `default-gutter-visible-p' for more information. | 1519 See `default-gutter-visible-p' for more information. |
1185 */ ); | 1520 */ ); |
1186 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean); | 1521 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qgutter_visible); |
1187 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER], | 1522 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER], |
1188 offsetof (struct window, | 1523 offsetof (struct window, |
1189 gutter_visible_p[RIGHT_GUTTER]), | 1524 gutter_visible_p[RIGHT_GUTTER]), |
1190 gutter_geometry_changed_in_window, | 1525 right_gutter_specs_changed, 0, 0); |
1191 0, 0); | |
1192 | 1526 |
1193 /* initially, top inherits from default; this can be | 1527 /* initially, top inherits from default; this can be |
1194 changed with `set-default-gutter-position'. */ | 1528 changed with `set-default-gutter-position'. */ |
1195 fb = list1 (Fcons (Qnil, Qt)); | 1529 fb = list1 (Fcons (Qnil, Qt)); |
1196 set_specifier_fallback (Vdefault_gutter_visible_p, fb); | 1530 set_specifier_fallback (Vdefault_gutter_visible_p, fb); |