comparison src/gutter.c @ 404:2f8bb876ab1d r21-2-32

Import from CVS: tag r21-2-32
author cvs
date Mon, 13 Aug 2007 11:16:07 +0200
parents a86b2b5e0111
children b8cc9ab3f761
comparison
equal deleted inserted replaced
403:9f011ab08d48 404:2f8bb876ab1d
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;
50 52
51 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \ 53 #define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
52 do { \ 54 do { \
53 switch (pos) \ 55 switch (pos) \
54 { \ 56 { \
84 default: 86 default:
85 abort (); 87 abort ();
86 } 88 }
87 } 89 }
88 90
91 #if 0
89 static Lisp_Object 92 static Lisp_Object
90 frame_topmost_window (struct frame *f) 93 frame_topmost_window (struct frame *f)
91 { 94 {
92 Lisp_Object w = FRAME_ROOT_WINDOW (f); 95 Lisp_Object w = FRAME_ROOT_WINDOW (f);
93 96
98 } 101 }
99 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild)); 102 } while (!NILP (XWINDOW (w)->hchild) && !NILP (w = XWINDOW (w)->hchild));
100 103
101 return w; 104 return w;
102 } 105 }
106 #endif
103 107
104 static Lisp_Object 108 static Lisp_Object
105 frame_bottommost_window (struct frame *f) 109 frame_bottommost_window (struct frame *f)
106 { 110 {
107 Lisp_Object w = FRAME_ROOT_WINDOW (f); 111 Lisp_Object w = FRAME_ROOT_WINDOW (f);
165 static void 169 static void
166 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y, 170 get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
167 int *width, int *height) 171 int *width, int *height)
168 { 172 {
169 struct window 173 struct window
170 * top = XWINDOW (frame_topmost_window (f)),
171 * bot = XWINDOW (frame_bottommost_window (f)); 174 * bot = XWINDOW (frame_bottommost_window (f));
172 /* The top and bottom gutters take precedence over the left and 175 /* The top and bottom gutters take precedence over the left and
173 right. */ 176 right. */
174 switch (pos) 177 switch (pos)
175 { 178 {
181 *height = FRAME_TOP_GUTTER_BOUNDS (f); 184 *height = FRAME_TOP_GUTTER_BOUNDS (f);
182 break; 185 break;
183 186
184 case BOTTOM_GUTTER: 187 case BOTTOM_GUTTER:
185 *x = FRAME_LEFT_BORDER_END (f); 188 *x = FRAME_LEFT_BORDER_END (f);
186 *y = WINDOW_BOTTOM (bot) 189 *y = WINDOW_BOTTOM (bot);
187 - FRAME_BOTTOM_GUTTER_BOUNDS (f);
188 *width = FRAME_RIGHT_BORDER_START (f) 190 *width = FRAME_RIGHT_BORDER_START (f)
189 - FRAME_LEFT_BORDER_END (f); 191 - FRAME_LEFT_BORDER_END (f);
190 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f); 192 *height = FRAME_BOTTOM_GUTTER_BOUNDS (f);
191 break; 193 break;
192 194
193 case LEFT_GUTTER: 195 case LEFT_GUTTER:
194 *x = FRAME_LEFT_BORDER_END (f); 196 *x = FRAME_LEFT_BORDER_END (f);
195 *y = WINDOW_TEXT_TOP (top); 197 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
196 *width = FRAME_LEFT_GUTTER_BOUNDS (f); 198 *width = FRAME_LEFT_GUTTER_BOUNDS (f);
197 *height = WINDOW_BOTTOM (bot) 199 *height = WINDOW_BOTTOM (bot)
198 - (WINDOW_TEXT_TOP (top) 200 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
199 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
200 break; 201 break;
201 202
202 case RIGHT_GUTTER: 203 case RIGHT_GUTTER:
203 *x = FRAME_RIGHT_BORDER_START (f) 204 *x = FRAME_RIGHT_BORDER_START (f)
204 - FRAME_RIGHT_GUTTER_BOUNDS (f); 205 - FRAME_RIGHT_GUTTER_BOUNDS (f);
205 *y = WINDOW_TEXT_TOP (top); 206 *y = FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f);
206 *width = FRAME_RIGHT_GUTTER_BOUNDS (f); 207 *width = FRAME_RIGHT_GUTTER_BOUNDS (f);
207 *height = WINDOW_BOTTOM (bot) 208 *height = WINDOW_BOTTOM (bot)
208 - (WINDOW_TEXT_TOP (top) 209 - (FRAME_TOP_BORDER_END (f) + FRAME_TOP_GUTTER_BOUNDS (f));
209 + FRAME_BOTTOM_GUTTER_BOUNDS (f));
210 break; 210 break;
211 211
212 default: 212 default:
213 abort (); 213 abort ();
214 } 214 }
215 } 215 }
216 216
217 static void 217 /* Convert the gutter specifier into something we can actually
218 output_gutter (struct frame *f, enum gutter_pos pos) 218 display. */
219 static Lisp_Object construct_window_gutter_spec (struct window* w,
220 enum gutter_pos pos)
221 {
222 Lisp_Object rest, *args;
223 int nargs = 0;
224 Lisp_Object gutter = RAW_WINDOW_GUTTER (w, pos);
225
226 if (STRINGP (gutter) || NILP (gutter))
227 return gutter;
228
229 GET_LIST_LENGTH (gutter, nargs);
230 args = alloca_array (Lisp_Object, nargs >> 1);
231 nargs = 0;
232
233 for (rest = gutter; !NILP (rest); rest = XCDR (XCDR (rest)))
234 {
235 /* We only put things in the real gutter that are declared to be
236 visible. */
237 if (!CONSP (WINDOW_GUTTER_VISIBLE (w, pos))
238 ||
239 !NILP (Fmemq (XCAR (rest), WINDOW_GUTTER_VISIBLE (w, pos))))
240 {
241 args [nargs++] = XCAR (XCDR (rest));
242 }
243 }
244
245 return Fconcat (nargs, args);
246 }
247
248 static void
249 output_gutter (struct frame *f, enum gutter_pos pos, int force)
219 { 250 {
220 Lisp_Object frame; 251 Lisp_Object frame;
221 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); 252 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
222 struct device *d = XDEVICE (f->device); 253 struct device *d = XDEVICE (f->device);
223 struct window* w = XWINDOW (window); 254 struct window* w = XWINDOW (window);
230 261
231 if (!WINDOW_LIVE_P (w)) 262 if (!WINDOW_LIVE_P (w))
232 return; 263 return;
233 264
234 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos); 265 border_width = FRAME_GUTTER_BORDER_WIDTH (f, pos);
235 findex = get_builtin_face_cache_index (w, Vgui_element_face); 266 findex = get_builtin_face_cache_index (w, Vwidget_face);
236 267
237 if (!f->current_display_lines) 268 if (!f->current_display_lines[pos])
238 f->current_display_lines = Dynarr_new (display_line); 269 f->current_display_lines[pos] = Dynarr_new (display_line);
239 if (!f->desired_display_lines) 270 if (!f->desired_display_lines[pos])
240 f->desired_display_lines = Dynarr_new (display_line); 271 f->desired_display_lines[pos] = Dynarr_new (display_line);
241 272
242 ddla = f->desired_display_lines; 273 ddla = f->desired_display_lines[pos];
243 cdla = f->current_display_lines; 274 cdla = f->current_display_lines[pos];
244 cdla_len = Dynarr_length (cdla); 275 cdla_len = Dynarr_length (cdla);
245 276
246 XSETFRAME (frame, f); 277 XSETFRAME (frame, f);
247 278
248 get_gutter_coords (f, pos, &x, &y, &width, &height); 279 get_gutter_coords (f, pos, &x, &y, &width, &height);
249 /* generate some display lines */ 280 /* generate some display lines */
250 generate_displayable_area (w, WINDOW_GUTTER (w, pos), 281 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
251 x + border_width, y + border_width, 282 x + border_width, y + border_width,
252 width - 2 * border_width, 283 width - 2 * border_width,
253 height - 2 * border_width, ddla, 0, findex); 284 height - 2 * border_width, ddla, 0, findex);
254 /* Output each line. */ 285
255 for (line = 0; line < Dynarr_length (ddla); line++) 286 /* We only output the gutter if we think something of significance
256 { 287 has changed. This is, for example, because redisplay can cause
257 output_display_line (w, cdla, ddla, line, -1, -1); 288 new face cache elements to get added causing compare_runes to
258 } 289 fail because the findex for a particular face has changed. */
259 290 if (force || f->faces_changed || f->frame_changed ||
260 /* If the number of display lines has shrunk, adjust. */ 291 f->gutter_changed || f->glyphs_changed ||
261 if (cdla_len > Dynarr_length (ddla)) 292 f->size_changed || f->subwindows_changed ||
262 { 293 w->windows_changed || f->windows_structure_changed ||
263 Dynarr_length (cdla) = Dynarr_length (ddla); 294 cdla_len != Dynarr_length (ddla) ||
264 } 295 (f->extents_changed && w->gutter_extent_modiff[pos]))
265 296 {
266 /* grab coordinates of last line and blank after it. */ 297 #ifdef DEBUG_GUTTERS
267 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); 298 printf ("gutter redisplay triggered by %s\n", force ? "force" :
268 ypos = dl->ypos + dl->descent - dl->clip; 299 f->faces_changed ? "f->faces_changed" :
269 redisplay_clear_region (window, findex, x + border_width , ypos, 300 f->frame_changed ? "f->frame_changed" :
270 width - 2 * border_width, height - (ypos - y) - border_width); 301 f->gutter_changed ? "f->gutter_changed" :
271 /* bevel the gutter area if so desired */ 302 f->glyphs_changed ? "f->glyphs_changed" :
272 if (border_width != 0) 303 f->size_changed ? "f->size_changed" :
273 { 304 f->subwindows_changed ? "f->subwindows_changed" :
274 MAYBE_DEVMETH (d, bevel_area, 305 w->windows_changed ? "w->windows_changed" :
275 (w, findex, x, y, width, height, border_width, 306 f->windows_structure_changed ? "f->windows_structure_changed" :
276 EDGE_ALL, EDGE_BEVEL_OUT)); 307 cdla_len != Dynarr_length (ddla) ? "different display structures" :
277 } 308 f->extents_changed && w->gutter_extent_modiff[pos] ?
278 } 309 "f->extents_changed && w->gutter_extent_modiff[pos]" : "<null>");
279 310 #endif
280 /* sizing gutters is a pain so we try and help the user by detemining 311 /* Output each line. */
312 for (line = 0; line < Dynarr_length (ddla); line++)
313 {
314 output_display_line (w, cdla, ddla, line, -1, -1);
315 }
316
317 /* If the number of display lines has shrunk, adjust. */
318 if (cdla_len > Dynarr_length (ddla))
319 {
320 Dynarr_length (cdla) = Dynarr_length (ddla);
321 }
322
323 /* grab coordinates of last line and blank after it. */
324 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
325 ypos = dl->ypos + dl->descent - dl->clip;
326 redisplay_clear_region (window, findex, x + border_width , ypos,
327 width - 2 * border_width, height - (ypos - y) - border_width);
328 /* bevel the gutter area if so desired */
329 if (border_width != 0)
330 {
331 MAYBE_DEVMETH (d, bevel_area,
332 (w, findex, x, y, width, height, border_width,
333 EDGE_ALL, EDGE_BEVEL_OUT));
334 }
335 }
336 else
337 {
338 /* Nothing of significance happened so sync the display line
339 structs. */
340 for (line = 0; line < Dynarr_length (ddla); line++)
341 {
342 sync_display_line_structs (w, line, 1, cdla, ddla);
343 }
344 }
345
346 w->gutter_extent_modiff [pos] = 0;
347 }
348
349 /* Sizing gutters is a pain so we try and help the user by detemining
281 what height will accommodate all lines. This is useless on left and 350 what height will accommodate all lines. This is useless on left and
282 right gutters as we always have a maximal number of lines. */ 351 right gutters as we always have a maximal number of lines. */
283 static Lisp_Object 352 static Lisp_Object
284 calculate_gutter_size (struct window *w, enum gutter_pos pos) 353 calculate_gutter_size (struct window *w, enum gutter_pos pos)
285 { 354 {
286 struct frame* f = XFRAME (WINDOW_FRAME (w)); 355 struct frame* f = XFRAME (WINDOW_FRAME (w));
287 int ypos; 356 int ypos, count;
288 display_line_dynarr* ddla; 357 display_line_dynarr* ddla;
289 struct display_line *dl; 358 struct display_line *dl;
290 359
291 /* we cannot autodetect gutter sizes for the left and right as there 360 /* we cannot autodetect gutter sizes for the left and right as there
292 is no reasonable metric to use */ 361 is no reasonable metric to use */
293 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER); 362 assert (pos == TOP_GUTTER || pos == BOTTOM_GUTTER);
294 /* degenerate case */ 363 /* degenerate case */
295 if (NILP (WINDOW_GUTTER (w, pos)) 364 if (NILP (RAW_WINDOW_GUTTER (w, pos))
296 || 365 ||
297 !FRAME_VISIBLE_P (f) 366 !FRAME_VISIBLE_P (f)
298 || 367 ||
299 NILP (w->buffer)) 368 NILP (w->buffer))
300 return Qnil; 369 return Qnil;
370
371 /* Redisplay code that we use relies on GC not happening. Make it
372 so. */
373 count = specpdl_depth ();
374 record_unwind_protect (restore_gc_inhibit,
375 make_int (gc_currently_forbidden));
376 gc_currently_forbidden = 1;
301 377
302 ddla = Dynarr_new (display_line); 378 ddla = Dynarr_new (display_line);
303 /* generate some display lines */ 379 /* generate some display lines */
304 generate_displayable_area (w, WINDOW_GUTTER (w, pos), 380 generate_displayable_area (w, WINDOW_GUTTER (w, pos),
305 FRAME_LEFT_BORDER_END (f), 381 FRAME_LEFT_BORDER_END (f),
306 0, 382 0,
307 FRAME_RIGHT_BORDER_START (f) 383 FRAME_RIGHT_BORDER_START (f)
308 - FRAME_LEFT_BORDER_END (f), 384 - FRAME_LEFT_BORDER_END (f),
309 200, 385 200,
310 ddla, 0, 0); 386 ddla, 0, 0);
387
388 /* Let GC happen again. */
389 unbind_to (count, Qnil);
390
311 /* grab coordinates of last line */ 391 /* grab coordinates of last line */
312 if (Dynarr_length (ddla)) 392 if (Dynarr_length (ddla))
313 { 393 {
314 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1); 394 dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
315 ypos = dl->ypos + dl->descent - dl->clip; 395 ypos = dl->ypos + dl->descent - dl->clip;
327 clear_gutter (struct frame *f, enum gutter_pos pos) 407 clear_gutter (struct frame *f, enum gutter_pos pos)
328 { 408 {
329 int x, y, width, height; 409 int x, y, width, height;
330 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f); 410 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
331 face_index findex = get_builtin_face_cache_index (XWINDOW (window), 411 face_index findex = get_builtin_face_cache_index (XWINDOW (window),
332 Vgui_element_face); 412 Vwidget_face);
333 get_gutter_coords (f, pos, &x, &y, &width, &height); 413 get_gutter_coords (f, pos, &x, &y, &width, &height);
334 414
335 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0); 415 SET_GUTTER_WAS_VISIBLE_FLAG (f, pos, 0);
336 416
337 redisplay_clear_region (window, findex, x, y, width, height); 417 redisplay_clear_region (window, findex, x, y, width, height);
345 /* See the comment in image_instantiate_cache_result as to why marking 425 /* See the comment in image_instantiate_cache_result as to why marking
346 the glyph will also mark the image_instance. */ 426 the glyph will also mark the image_instance. */
347 void 427 void
348 mark_gutters (struct frame* f) 428 mark_gutters (struct frame* f)
349 { 429 {
350 if (f->current_display_lines) 430 enum gutter_pos pos;
351 mark_redisplay_structs (f->current_display_lines); 431 GUTTER_POS_LOOP (pos)
352 if (f->desired_display_lines) 432 {
353 mark_redisplay_structs (f->desired_display_lines); 433 if (f->current_display_lines[pos])
434 mark_redisplay_structs (f->current_display_lines[pos]);
435 /* #### Do we really need to mark the desired lines? */
436 if (f->desired_display_lines[pos])
437 mark_redisplay_structs (f->desired_display_lines[pos]);
438 }
439 }
440
441 /* This is called by extent_changed_for_redisplay, so that redisplay
442 knows exactly what extents have changed. */
443 void
444 gutter_extent_signal_changed_region_maybe (Lisp_Object obj,
445 Bufpos start, Bufpos end)
446 {
447 /* #### Start and end are currently ignored but could be used by a
448 more optimal gutter redisplay. We currently loop over all frames
449 here, this could be optimized. */
450 Lisp_Object frmcons, devcons, concons;
451
452 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
453 {
454 struct frame *f = XFRAME (XCAR (frmcons));
455 enum gutter_pos pos;
456 Lisp_Object window = FRAME_LAST_NONMINIBUF_WINDOW (f);
457 struct window* w = XWINDOW (window);
458
459 GUTTER_POS_LOOP (pos)
460 {
461 if (EQ (WINDOW_GUTTER (w, pos), obj))
462 {
463 w->gutter_extent_modiff[pos]++;
464 }
465 }
466 }
467 }
468
469 /* We have to change the gutter geometry separately to the gutter
470 update since it needs to occur outside of redisplay proper. */
471 void
472 update_frame_gutter_geometry (struct frame *f)
473 {
474 if (f->gutter_changed || f->windows_structure_changed)
475 {
476 enum gutter_pos pos;
477
478 /* If the gutter geometry has changed then re-layout the
479 frame. If we are in display there is almost no point in doing
480 anything else since the frame size changes will be delayed
481 until we are out of redisplay proper. */
482 GUTTER_POS_LOOP (pos)
483 {
484 if (FRAME_GUTTER_BOUNDS (f, pos) != f->current_gutter_bounds[pos])
485 {
486 int width, height;
487 pixel_to_char_size (f, FRAME_PIXWIDTH (f), FRAME_PIXHEIGHT (f),
488 &width, &height);
489 change_frame_size (f, height, width, 0);
490 break;
491 }
492 }
493
494 GUTTER_POS_LOOP (pos)
495 {
496 /* Mark sizes as up-to-date. */
497 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
498 }
499 }
354 } 500 }
355 501
356 void 502 void
357 update_frame_gutters (struct frame *f) 503 update_frame_gutters (struct frame *f)
358 { 504 {
359 if (f->gutter_changed || f->clear || 505 if (f->faces_changed || f->frame_changed ||
360 f->glyphs_changed || f->subwindows_changed || 506 f->gutter_changed || f->glyphs_changed ||
361 f->windows_changed || f->windows_structure_changed || 507 f->size_changed || f->subwindows_changed ||
362 f->extents_changed || f->faces_changed) 508 f->windows_changed || f->windows_structure_changed ||
509 f->extents_changed)
363 { 510 {
364 enum gutter_pos pos; 511 enum gutter_pos pos;
365 512
366 /* We don't actually care about these when outputting the gutter 513 /* We don't actually care about these when outputting the gutter
367 so locally disable them. */ 514 so locally disable them. */
372 519
373 /* and output */ 520 /* and output */
374 GUTTER_POS_LOOP (pos) 521 GUTTER_POS_LOOP (pos)
375 { 522 {
376 if (FRAME_GUTTER_VISIBLE (f, pos)) 523 if (FRAME_GUTTER_VISIBLE (f, pos))
377 output_gutter (f, pos); 524 output_gutter (f, pos, 0);
525
378 else if (gutter_was_visible (f, pos)) 526 else if (gutter_was_visible (f, pos))
379 clear_gutter (f, pos); 527 clear_gutter (f, pos);
380 } 528 }
529
381 f->clip_changed = local_clip_changed; 530 f->clip_changed = local_clip_changed;
382 f->buffers_changed = local_buffers_changed; 531 f->buffers_changed = local_buffers_changed;
383 f->gutter_changed = 0; 532 f->gutter_changed = 0;
384 } 533 }
385 } 534 }
386 535
387 void 536 void
388 reset_gutter_display_lines (struct frame* f) 537 reset_gutter_display_lines (struct frame* f)
389 { 538 {
390 if (f->current_display_lines) 539 enum gutter_pos pos;
391 Dynarr_reset (f->current_display_lines); 540 GUTTER_POS_LOOP (pos)
541 {
542 if (f->current_display_lines[pos])
543 Dynarr_reset (f->current_display_lines[pos]);
544 }
392 } 545 }
393 546
394 static void 547 static void
395 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y, 548 redraw_exposed_gutter (struct frame *f, enum gutter_pos pos, int x, int y,
396 int width, int height) 549 int width, int height)
410 reset_gutter_display_lines (f); 563 reset_gutter_display_lines (f);
411 564
412 /* Even if none of the gutter is in the area, the blank region at 565 /* Even if none of the gutter is in the area, the blank region at
413 the very least must be because the first thing we did is verify 566 the very least must be because the first thing we did is verify
414 that some portion of the gutter is in the exposed region. */ 567 that some portion of the gutter is in the exposed region. */
415 output_gutter (f, pos); 568 output_gutter (f, pos, 1);
416 } 569 }
417 570
418 void 571 void
419 redraw_exposed_gutters (struct frame *f, int x, int y, int width, 572 redraw_exposed_gutters (struct frame *f, int x, int y, int width,
420 int height) 573 int height)
428 } 581 }
429 582
430 void 583 void
431 free_frame_gutters (struct frame *f) 584 free_frame_gutters (struct frame *f)
432 { 585 {
433 if (f->current_display_lines) 586 enum gutter_pos pos;
434 { 587 GUTTER_POS_LOOP (pos)
435 free_display_lines (f->current_display_lines); 588 {
436 f->current_display_lines = 0; 589 if (f->current_display_lines[pos])
437 } 590 {
438 if (f->desired_display_lines) 591 free_display_lines (f->current_display_lines[pos]);
439 { 592 f->current_display_lines[pos] = 0;
440 free_display_lines (f->desired_display_lines); 593 }
441 f->desired_display_lines = 0; 594 if (f->desired_display_lines[pos])
595 {
596 free_display_lines (f->desired_display_lines[pos]);
597 f->desired_display_lines[pos] = 0;
598 }
442 } 599 }
443 } 600 }
444 601
445 static enum gutter_pos 602 static enum gutter_pos
446 decode_gutter_position (Lisp_Object position) 603 decode_gutter_position (Lisp_Object position)
480 : Vdefault_gutter_width); 637 : Vdefault_gutter_width);
481 set_specifier_fallback (Vgutter_border_width[cur], 638 set_specifier_fallback (Vgutter_border_width[cur],
482 list1 (Fcons (Qnil, Qzero))); 639 list1 (Fcons (Qnil, Qzero)));
483 set_specifier_fallback (Vgutter_border_width[new], 640 set_specifier_fallback (Vgutter_border_width[new],
484 Vdefault_gutter_border_width); 641 Vdefault_gutter_border_width);
642 /* We don't realy want the left and right gutters to default to
643 visible. */
485 set_specifier_fallback (Vgutter_visible_p[cur], 644 set_specifier_fallback (Vgutter_visible_p[cur],
486 list1 (Fcons (Qnil, Qt))); 645 cur == TOP_GUTTER || cur == BOTTOM_GUTTER ?
646 list1 (Fcons (Qnil, Qt))
647 : list1 (Fcons (Qnil, Qnil)));
487 set_specifier_fallback (Vgutter_visible_p[new], 648 set_specifier_fallback (Vgutter_visible_p[new],
488 Vdefault_gutter_visible_p); 649 Vdefault_gutter_visible_p);
650
489 Vdefault_gutter_position = position; 651 Vdefault_gutter_position = position;
490 unhold_frame_size_changes (); 652 unhold_frame_size_changes ();
491 } 653 }
492 654
655 run_hook (Qdefault_gutter_position_changed_hook);
656
493 return position; 657 return position;
494 } 658 }
495 659
496 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /* 660 DEFUN ("default-gutter-position", Fdefault_gutter_position, 0, 0, 0, /*
497 Return the position that the `default-gutter' will be displayed at. 661 Return the position that the `default-gutter' will be displayed at.
556 static void 720 static void
557 gutter_validate (Lisp_Object instantiator) 721 gutter_validate (Lisp_Object instantiator)
558 { 722 {
559 if (NILP (instantiator)) 723 if (NILP (instantiator))
560 return; 724 return;
725
726 /* Must be a string or a plist. */
727 if (!STRINGP (instantiator) && NILP (Fvalid_plist_p (instantiator)))
728 signal_simple_error ("Gutter spec must be string, plist or nil", instantiator);
561 729
562 if (!STRINGP (instantiator)) 730 if (!STRINGP (instantiator))
563 signal_simple_error ("Gutter spec must be string or nil", instantiator); 731 {
732 Lisp_Object rest;
733
734 for (rest = instantiator; !NILP (rest); rest = XCDR (XCDR (rest)))
735 {
736 if (!SYMBOLP (XCAR (rest))
737 || !STRINGP (XCAR (XCDR (rest))))
738 signal_simple_error ("Gutter plist spec must contain strings", instantiator);
739 }
740 }
564 } 741 }
565 742
566 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /* 743 DEFUN ("gutter-specifier-p", Fgutter_specifier_p, 1, 1, 0, /*
567 Return non-nil if OBJECT is a gutter specifier. 744 Return non-nil if OBJECT is a gutter specifier.
568 Gutter specifiers are used to specify the format of a gutter. 745 Gutter specifiers are used to specify the format of a gutter.
569 The values of the variables `default-gutter', `top-gutter', 746 The values of the variables `default-gutter', `top-gutter',
570 `left-gutter', `right-gutter', and `bottom-gutter' are always 747 `left-gutter', `right-gutter', and `bottom-gutter' are always
571 gutter specifiers. 748 gutter specifiers.
572 749
573 Valid gutter instantiators are called "gutter descriptors" 750 Valid gutter instantiators are called "gutter descriptors" and are
574 and are lists of vectors. See `default-gutter' for a description 751 either strings or property-lists of strings. See `default-gutter' for
575 of the exact format. 752 a description of the exact format.
576 */ 753 */
577 (object)) 754 (object))
578 { 755 {
579 return GUTTER_SPECIFIERP (object) ? Qt : Qnil; 756 return GUTTER_SPECIFIERP (object) ? Qt : Qnil;
580 } 757 }
591 Fset_specifier_dirty_flag (real_one[pos]); 768 Fset_specifier_dirty_flag (real_one[pos]);
592 } 769 }
593 770
594 static void 771 static void
595 gutter_specs_changed (Lisp_Object specifier, struct window *w, 772 gutter_specs_changed (Lisp_Object specifier, struct window *w,
596 Lisp_Object oldval) 773 Lisp_Object oldval, enum gutter_pos pos)
774 {
775 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
776 w->real_gutter_size[pos] = w->gutter_size[pos];
777
778 if (EQ (w->real_gutter_size[pos], Qautodetect)
779 && !NILP (w->gutter_visible_p[pos]))
780 {
781 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
782 }
783 MARK_GUTTER_CHANGED;
784 MARK_MODELINE_CHANGED;
785 MARK_WINDOWS_CHANGED (w);
786 }
787
788 /* We define all of these so we can access which actual gutter changed. */
789 static void
790 top_gutter_specs_changed (Lisp_Object specifier, struct window *w,
791 Lisp_Object oldval)
792 {
793 gutter_specs_changed (specifier, w, oldval, TOP_GUTTER);
794 }
795
796 static void
797 bottom_gutter_specs_changed (Lisp_Object specifier, struct window *w,
798 Lisp_Object oldval)
799 {
800 gutter_specs_changed (specifier, w, oldval, BOTTOM_GUTTER);
801 }
802
803 static void
804 left_gutter_specs_changed (Lisp_Object specifier, struct window *w,
805 Lisp_Object oldval)
806 {
807 gutter_specs_changed (specifier, w, oldval, LEFT_GUTTER);
808 }
809
810 static void
811 right_gutter_specs_changed (Lisp_Object specifier, struct window *w,
812 Lisp_Object oldval)
813 {
814 gutter_specs_changed (specifier, w, oldval, RIGHT_GUTTER);
815 }
816
817 static void
818 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
819 Lisp_Object oldval)
820 {
821 recompute_overlaying_specifier (Vgutter);
822 }
823
824 static void
825 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
826 Lisp_Object oldval)
597 { 827 {
598 enum gutter_pos pos; 828 enum gutter_pos pos;
599 GUTTER_POS_LOOP (pos) 829 GUTTER_POS_LOOP (pos)
600 { 830 {
601 w->real_gutter_size[pos] = w->gutter_size[pos]; 831 w->real_gutter_size[pos] = w->gutter_size[pos];
603 && !NILP (w->gutter_visible_p[pos])) 833 && !NILP (w->gutter_visible_p[pos]))
604 { 834 {
605 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); 835 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
606 } 836 }
607 } 837 }
608 MARK_GUTTER_CHANGED;
609 MARK_WINDOWS_CHANGED (w);
610 }
611
612 static void
613 default_gutter_specs_changed (Lisp_Object specifier, struct window *w,
614 Lisp_Object oldval)
615 {
616 recompute_overlaying_specifier (Vgutter);
617 }
618
619 static void
620 gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
621 Lisp_Object oldval)
622 {
623 enum gutter_pos pos;
624 GUTTER_POS_LOOP (pos)
625 {
626 w->real_gutter_size[pos] = w->gutter_size[pos];
627 if (EQ (w->real_gutter_size[pos], Qautodetect)
628 && !NILP (w->gutter_visible_p[pos]))
629 {
630 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
631 }
632 }
633 838
634 MARK_GUTTER_CHANGED; 839 MARK_GUTTER_CHANGED;
840 MARK_MODELINE_CHANGED;
635 MARK_WINDOWS_CHANGED (w); 841 MARK_WINDOWS_CHANGED (w);
636 } 842 }
637 843
638 static void 844 static void
639 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w, 845 default_gutter_size_changed_in_window (Lisp_Object specifier, struct window *w,
654 default_gutter_visible_p_changed_in_window (Lisp_Object specifier, 860 default_gutter_visible_p_changed_in_window (Lisp_Object specifier,
655 struct window *w, 861 struct window *w,
656 Lisp_Object oldval) 862 Lisp_Object oldval)
657 { 863 {
658 recompute_overlaying_specifier (Vgutter_visible_p); 864 recompute_overlaying_specifier (Vgutter_visible_p);
865 /* Need to reconstruct the gutter specifier as it is affected by the
866 visibility. */
867 recompute_overlaying_specifier (Vgutter);
659 } 868 }
660 869
661 870
662 DECLARE_SPECIFIER_TYPE (gutter_size); 871 DECLARE_SPECIFIER_TYPE (gutter_size);
663 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size) 872 #define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
673 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator); 882 signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
674 } 883 }
675 884
676 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /* 885 DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
677 Return non-nil if OBJECT is a gutter-size specifier. 886 Return non-nil if OBJECT is a gutter-size specifier.
887
888 Gutter-size specifiers are used to specify the size of a gutter. The
889 values of the variables `default-gutter-size', `top-gutter-size',
890 `left-gutter-size', `right-gutter-size', and `bottom-gutter-size' are
891 always gutter-size specifiers.
892
893 Valid gutter-size instantiators are either integers or the special
894 symbol 'autodetect. If a gutter-size is set to 'autodetect them the
895 size of the gutter will be adjusted to just accomodate the gutters
896 contents. 'autodetect only works for top and bottom gutters.
678 */ 897 */
679 (object)) 898 (object))
680 { 899 {
681 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil; 900 return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
901 }
902
903 DECLARE_SPECIFIER_TYPE (gutter_visible);
904 #define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible)
905 DEFINE_SPECIFIER_TYPE (gutter_visible);
906
907 static void
908 gutter_visible_validate (Lisp_Object instantiator)
909 {
910 if (NILP (instantiator))
911 return;
912
913 if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator))
914 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
915 instantiator);
916
917 if (CONSP (instantiator))
918 {
919 Lisp_Object rest;
920
921 EXTERNAL_LIST_LOOP (rest, instantiator)
922 {
923 if (!SYMBOLP (XCAR (rest)))
924 signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
925 instantiator);
926 }
927 }
928 }
929
930 DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /*
931 Return non-nil if OBJECT is a gutter-visible specifier.
932
933 Gutter-visible specifiers are used to specify the visibility of a
934 gutter. The values of the variables `default-gutter-visible-p',
935 `top-gutter-visible-p', `left-gutter-visible-p',
936 `right-gutter-visible-p', and `bottom-gutter-visible-p' are always
937 gutter-visible specifiers.
938
939 Valid gutter-visible instantiators are t, nil or a list of symbols.
940 If a gutter-visible instantiator is set to a list of symbols, and the
941 correspondong gutter specification is a property-list strings, then
942 elements of the gutter specification will only be visible if the
943 corresponding symbol occurs in the gutter-visible instantiator.
944 */
945 (object))
946 {
947 return GUTTER_VISIBLE_SPECIFIERP (object) ? Qt : Qnil;
682 } 948 }
683 949
684 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /* 950 DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
685 Ensure that all gutters are correctly showing their gutter specifier. 951 Ensure that all gutters are correctly showing their gutter specifier.
686 */ 952 */
694 Lisp_Object frmcons; 960 Lisp_Object frmcons;
695 961
696 DEVICE_FRAME_LOOP (frmcons, d) 962 DEVICE_FRAME_LOOP (frmcons, d)
697 { 963 {
698 struct frame *f = XFRAME (XCAR (frmcons)); 964 struct frame *f = XFRAME (XCAR (frmcons));
699 965
700 if (FRAME_REPAINT_P (f)) 966 /* Sequence is quite important here. We not only want to
967 redisplay the gutter area but we also want to flush any
968 frame size changes out so that the gutter redisplay happens
969 in a kosha environment.
970
971 This is not only so that things look right but so that
972 glyph redisplay optimization kicks in, by default display
973 lines will be completely re-output if
974 f->windows_structure_changed is 1, and this is true if
975 frame size changes haven't been flushed out. Once frame
976 size changes have been flushed out we then need to
977 redisplay the frame in order to flush out pending window
978 size changes. */
979 update_frame_gutter_geometry (f);
980
981 if (f->windows_structure_changed)
982 redisplay_frame (f, 1);
983 else if (FRAME_REPAINT_P (f))
701 { 984 {
985 /* We have to be "in display" when we output the gutter
986 - make it so. */
987 hold_frame_size_changes ();
702 update_frame_gutters (f); 988 update_frame_gutters (f);
989 unhold_one_frame_size_changes (f);
703 } 990 }
704 } 991 }
705
706 /* We now call the output_end routine for tty frames. We delay 992 /* We now call the output_end routine for tty frames. We delay
707 doing so in order to avoid cursor flicker. So much for 100% 993 doing so in order to avoid cursor flicker. So much for 100%
708 encapsulation. */ 994 encapsulation. */
709 if (DEVICE_TTY_P (d)) 995 if (DEVICE_TTY_P (d))
710 DEVMETH (d, output_end, (d)); 996 DEVMETH (d, output_end, (d));
711 } 997
998 d->gutter_changed = 0;
999 }
1000
1001 /* This is so that further changes to the gutters will trigger redisplay. */
1002 gutter_changed_set = 0;
1003 gutter_changed = 0;
712 1004
713 return Qnil; 1005 return Qnil;
714 } 1006 }
715 1007
716 void 1008 void
721 /* We are here as far in frame creation so cached specifiers are 1013 /* We are here as far in frame creation so cached specifiers are
722 already recomputed, and possibly modified by resource 1014 already recomputed, and possibly modified by resource
723 initialization. We need to recalculate autodetected gutters. */ 1015 initialization. We need to recalculate autodetected gutters. */
724 GUTTER_POS_LOOP (pos) 1016 GUTTER_POS_LOOP (pos)
725 { 1017 {
1018 w->real_gutter[pos] = construct_window_gutter_spec (w, pos);
726 w->real_gutter_size[pos] = w->gutter_size[pos]; 1019 w->real_gutter_size[pos] = w->gutter_size[pos];
727 if (EQ (w->gutter_size[pos], Qautodetect) 1020 if (EQ (w->gutter_size[pos], Qautodetect)
728 && !NILP (w->gutter_visible_p[pos])) 1021 && !NILP (w->gutter_visible_p[pos]))
729 { 1022 {
730 w->real_gutter_size [pos] = calculate_gutter_size (w, pos); 1023 w->real_gutter_size [pos] = calculate_gutter_size (w, pos);
731 MARK_GUTTER_CHANGED; 1024 MARK_GUTTER_CHANGED;
732 MARK_WINDOWS_CHANGED (w); 1025 MARK_WINDOWS_CHANGED (w);
733 } 1026 }
734 } 1027 }
1028
1029 /* Keep a record of the current sizes of things. */
1030 GUTTER_POS_LOOP (pos)
1031 {
1032 f->current_gutter_bounds[pos] = FRAME_GUTTER_BOUNDS (f, pos);
1033 }
735 } 1034 }
736 1035
737 void 1036 void
738 syms_of_gutter (void) 1037 syms_of_gutter (void)
739 { 1038 {
740 DEFSUBR (Fgutter_specifier_p); 1039 DEFSUBR (Fgutter_specifier_p);
741 DEFSUBR (Fgutter_size_specifier_p); 1040 DEFSUBR (Fgutter_size_specifier_p);
1041 DEFSUBR (Fgutter_visible_specifier_p);
742 DEFSUBR (Fset_default_gutter_position); 1042 DEFSUBR (Fset_default_gutter_position);
743 DEFSUBR (Fdefault_gutter_position); 1043 DEFSUBR (Fdefault_gutter_position);
744 DEFSUBR (Fgutter_pixel_height); 1044 DEFSUBR (Fgutter_pixel_height);
745 DEFSUBR (Fgutter_pixel_width); 1045 DEFSUBR (Fgutter_pixel_width);
746 DEFSUBR (Fredisplay_gutter_area); 1046 DEFSUBR (Fredisplay_gutter_area);
747 1047
748 defsymbol (&Qgutter_size, "gutter-size"); 1048 defsymbol (&Qgutter_size, "gutter-size");
1049 defsymbol (&Qgutter_visible, "gutter-visible");
1050 defsymbol (&Qdefault_gutter_position_changed_hook,
1051 "default-gutter-position-changed");
749 } 1052 }
750 1053
751 void 1054 void
752 vars_of_gutter (void) 1055 vars_of_gutter (void)
753 { 1056 {
759 1062
760 void 1063 void
761 specifier_type_create_gutter (void) 1064 specifier_type_create_gutter (void)
762 { 1065 {
763 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p"); 1066 INITIALIZE_SPECIFIER_TYPE (gutter, "gutter", "gutter-specifier-p");
764
765 SPECIFIER_HAS_METHOD (gutter, validate); 1067 SPECIFIER_HAS_METHOD (gutter, validate);
766 SPECIFIER_HAS_METHOD (gutter, after_change); 1068 SPECIFIER_HAS_METHOD (gutter, after_change);
767 1069
768 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p"); 1070 INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
769
770 SPECIFIER_HAS_METHOD (gutter_size, validate); 1071 SPECIFIER_HAS_METHOD (gutter_size, validate);
1072
1073 INITIALIZE_SPECIFIER_TYPE (gutter_visible, "gutter-visible", "gutter-visible-specifier-p");
1074 SPECIFIER_HAS_METHOD (gutter_visible, validate);
771 } 1075 }
772 1076
773 void 1077 void
774 reinit_specifier_type_create_gutter (void) 1078 reinit_specifier_type_create_gutter (void)
775 { 1079 {
776 REINITIALIZE_SPECIFIER_TYPE (gutter); 1080 REINITIALIZE_SPECIFIER_TYPE (gutter);
777 REINITIALIZE_SPECIFIER_TYPE (gutter_size); 1081 REINITIALIZE_SPECIFIER_TYPE (gutter_size);
1082 REINITIALIZE_SPECIFIER_TYPE (gutter_visible);
778 } 1083 }
779 1084
780 void 1085 void
781 specifier_vars_of_gutter (void) 1086 specifier_vars_of_gutter (void)
782 { 1087 {
813 the visibility and thickness using `default-gutter-visible-p', 1118 the visibility and thickness using `default-gutter-visible-p',
814 `default-gutter-width', and `default-gutter-height', rather than 1119 `default-gutter-width', and `default-gutter-height', rather than
815 using position-specific specifiers. That way, you will get sane 1120 using position-specific specifiers. That way, you will get sane
816 behavior if the user changes the default gutter position. 1121 behavior if the user changes the default gutter position.
817 1122
818 The gutter value should be a string or nil. You can attach extents and 1123 The gutter value should be a string, a property list of strings or
819 glyphs to the string and hence display glyphs and text in other fonts 1124 nil. You can attach extents and glyphs to the string and hence display
820 in the gutter area. 1125 glyphs and text in other fonts in the gutter area. If the gutter value
821 1126 is a property list then the strings will be concatenated together
822 */ ); 1127 before being displayed. */ );
823 1128
824 Vdefault_gutter = Fmake_specifier (Qgutter); 1129 Vdefault_gutter = Fmake_specifier (Qgutter);
825 /* #### It would be even nicer if the specifier caching 1130 /* #### It would be even nicer if the specifier caching
826 automatically knew about specifier fallbacks, so we didn't 1131 automatically knew about specifier fallbacks, so we didn't
827 have to do it ourselves. */ 1132 have to do it ourselves. */
837 See `default-gutter' for a description of a valid gutter instantiator. 1142 See `default-gutter' for a description of a valid gutter instantiator.
838 */ ); 1143 */ );
839 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter); 1144 Vgutter[TOP_GUTTER] = Fmake_specifier (Qgutter);
840 set_specifier_caching (Vgutter[TOP_GUTTER], 1145 set_specifier_caching (Vgutter[TOP_GUTTER],
841 offsetof (struct window, gutter[TOP_GUTTER]), 1146 offsetof (struct window, gutter[TOP_GUTTER]),
842 gutter_specs_changed, 1147 top_gutter_specs_changed,
843 0, 0); 1148 0, 0);
844 1149
845 DEFVAR_SPECIFIER ("bottom-gutter", 1150 DEFVAR_SPECIFIER ("bottom-gutter",
846 &Vgutter[BOTTOM_GUTTER] /* 1151 &Vgutter[BOTTOM_GUTTER] /*
847 Specifier for the gutter at the bottom of the frame. 1152 Specifier for the gutter at the bottom of the frame.
854 displayed even if you provide a value for `bottom-gutter'. 1159 displayed even if you provide a value for `bottom-gutter'.
855 */ ); 1160 */ );
856 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter); 1161 Vgutter[BOTTOM_GUTTER] = Fmake_specifier (Qgutter);
857 set_specifier_caching (Vgutter[BOTTOM_GUTTER], 1162 set_specifier_caching (Vgutter[BOTTOM_GUTTER],
858 offsetof (struct window, gutter[BOTTOM_GUTTER]), 1163 offsetof (struct window, gutter[BOTTOM_GUTTER]),
859 gutter_specs_changed, 1164 bottom_gutter_specs_changed,
860 0, 0); 1165 0, 0);
861 1166
862 DEFVAR_SPECIFIER ("left-gutter", 1167 DEFVAR_SPECIFIER ("left-gutter",
863 &Vgutter[LEFT_GUTTER] /* 1168 &Vgutter[LEFT_GUTTER] /*
864 Specifier for the gutter at the left edge of the frame. 1169 Specifier for the gutter at the left edge of the frame.
871 displayed even if you provide a value for `left-gutter'. 1176 displayed even if you provide a value for `left-gutter'.
872 */ ); 1177 */ );
873 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter); 1178 Vgutter[LEFT_GUTTER] = Fmake_specifier (Qgutter);
874 set_specifier_caching (Vgutter[LEFT_GUTTER], 1179 set_specifier_caching (Vgutter[LEFT_GUTTER],
875 offsetof (struct window, gutter[LEFT_GUTTER]), 1180 offsetof (struct window, gutter[LEFT_GUTTER]),
876 gutter_specs_changed, 1181 left_gutter_specs_changed,
877 0, 0); 1182 0, 0);
878 1183
879 DEFVAR_SPECIFIER ("right-gutter", 1184 DEFVAR_SPECIFIER ("right-gutter",
880 &Vgutter[RIGHT_GUTTER] /* 1185 &Vgutter[RIGHT_GUTTER] /*
881 Specifier for the gutter at the right edge of the frame. 1186 Specifier for the gutter at the right edge of the frame.
888 displayed even if you provide a value for `right-gutter'. 1193 displayed even if you provide a value for `right-gutter'.
889 */ ); 1194 */ );
890 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter); 1195 Vgutter[RIGHT_GUTTER] = Fmake_specifier (Qgutter);
891 set_specifier_caching (Vgutter[RIGHT_GUTTER], 1196 set_specifier_caching (Vgutter[RIGHT_GUTTER],
892 offsetof (struct window, gutter[RIGHT_GUTTER]), 1197 offsetof (struct window, gutter[RIGHT_GUTTER]),
893 gutter_specs_changed, 1198 right_gutter_specs_changed,
894 0, 0); 1199 0, 0);
895 1200
896 /* initially, top inherits from default; this can be 1201 /* initially, top inherits from default; this can be
897 changed with `set-default-gutter-position'. */ 1202 changed with `set-default-gutter-position'. */
898 fb = list1 (Fcons (Qnil, Qnil)); 1203 fb = list1 (Fcons (Qnil, Qnil));
953 See `default-gutter-height' for more information. 1258 See `default-gutter-height' for more information.
954 */ ); 1259 */ );
955 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size); 1260 Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
956 set_specifier_caching (Vgutter_size[TOP_GUTTER], 1261 set_specifier_caching (Vgutter_size[TOP_GUTTER],
957 offsetof (struct window, gutter_size[TOP_GUTTER]), 1262 offsetof (struct window, gutter_size[TOP_GUTTER]),
958 gutter_geometry_changed_in_window, 1263 gutter_geometry_changed_in_window, 0, 0);
959 0, 0);
960 1264
961 DEFVAR_SPECIFIER ("bottom-gutter-height", 1265 DEFVAR_SPECIFIER ("bottom-gutter-height",
962 &Vgutter_size[BOTTOM_GUTTER] /* 1266 &Vgutter_size[BOTTOM_GUTTER] /*
963 *Height of the bottom gutter. 1267 *Height of the bottom gutter.
964 This is a specifier; use `set-specifier' to change it. 1268 This is a specifier; use `set-specifier' to change it.
966 See `default-gutter-height' for more information. 1270 See `default-gutter-height' for more information.
967 */ ); 1271 */ );
968 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size); 1272 Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
969 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER], 1273 set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
970 offsetof (struct window, gutter_size[BOTTOM_GUTTER]), 1274 offsetof (struct window, gutter_size[BOTTOM_GUTTER]),
971 gutter_geometry_changed_in_window, 1275 gutter_geometry_changed_in_window, 0, 0);
972 0, 0);
973 1276
974 DEFVAR_SPECIFIER ("left-gutter-width", 1277 DEFVAR_SPECIFIER ("left-gutter-width",
975 &Vgutter_size[LEFT_GUTTER] /* 1278 &Vgutter_size[LEFT_GUTTER] /*
976 *Width of left gutter. 1279 *Width of left gutter.
977 This is a specifier; use `set-specifier' to change it. 1280 This is a specifier; use `set-specifier' to change it.
979 See `default-gutter-height' for more information. 1282 See `default-gutter-height' for more information.
980 */ ); 1283 */ );
981 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum); 1284 Vgutter_size[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
982 set_specifier_caching (Vgutter_size[LEFT_GUTTER], 1285 set_specifier_caching (Vgutter_size[LEFT_GUTTER],
983 offsetof (struct window, gutter_size[LEFT_GUTTER]), 1286 offsetof (struct window, gutter_size[LEFT_GUTTER]),
984 gutter_geometry_changed_in_window, 1287 gutter_geometry_changed_in_window, 0, 0);
985 0, 0);
986 1288
987 DEFVAR_SPECIFIER ("right-gutter-width", 1289 DEFVAR_SPECIFIER ("right-gutter-width",
988 &Vgutter_size[RIGHT_GUTTER] /* 1290 &Vgutter_size[RIGHT_GUTTER] /*
989 *Width of right gutter. 1291 *Width of right gutter.
990 This is a specifier; use `set-specifier' to change it. 1292 This is a specifier; use `set-specifier' to change it.
992 See `default-gutter-height' for more information. 1294 See `default-gutter-height' for more information.
993 */ ); 1295 */ );
994 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); 1296 Vgutter_size[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
995 set_specifier_caching (Vgutter_size[RIGHT_GUTTER], 1297 set_specifier_caching (Vgutter_size[RIGHT_GUTTER],
996 offsetof (struct window, gutter_size[RIGHT_GUTTER]), 1298 offsetof (struct window, gutter_size[RIGHT_GUTTER]),
997 gutter_geometry_changed_in_window, 1299 gutter_geometry_changed_in_window, 0, 0);
998 0, 0);
999 1300
1000 fb = Qnil; 1301 fb = Qnil;
1001 #ifdef HAVE_TTY 1302 #ifdef HAVE_TTY
1002 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb); 1303 fb = Fcons (Fcons (list1 (Qtty), Qautodetect), fb);
1003 #endif 1304 #endif
1061 */ ); 1362 */ );
1062 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum); 1363 Vgutter_border_width[TOP_GUTTER] = Fmake_specifier (Qnatnum);
1063 set_specifier_caching (Vgutter_border_width[TOP_GUTTER], 1364 set_specifier_caching (Vgutter_border_width[TOP_GUTTER],
1064 offsetof (struct window, 1365 offsetof (struct window,
1065 gutter_border_width[TOP_GUTTER]), 1366 gutter_border_width[TOP_GUTTER]),
1066 gutter_geometry_changed_in_window, 1367 gutter_geometry_changed_in_window, 0, 0);
1067 0, 0);
1068 1368
1069 DEFVAR_SPECIFIER ("bottom-gutter-border-width", 1369 DEFVAR_SPECIFIER ("bottom-gutter-border-width",
1070 &Vgutter_border_width[BOTTOM_GUTTER] /* 1370 &Vgutter_border_width[BOTTOM_GUTTER] /*
1071 *Border width of the bottom gutter. 1371 *Border width of the bottom gutter.
1072 This is a specifier; use `set-specifier' to change it. 1372 This is a specifier; use `set-specifier' to change it.
1075 */ ); 1375 */ );
1076 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum); 1376 Vgutter_border_width[BOTTOM_GUTTER] = Fmake_specifier (Qnatnum);
1077 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER], 1377 set_specifier_caching (Vgutter_border_width[BOTTOM_GUTTER],
1078 offsetof (struct window, 1378 offsetof (struct window,
1079 gutter_border_width[BOTTOM_GUTTER]), 1379 gutter_border_width[BOTTOM_GUTTER]),
1080 gutter_geometry_changed_in_window, 1380 gutter_geometry_changed_in_window, 0, 0);
1081 0, 0);
1082 1381
1083 DEFVAR_SPECIFIER ("left-gutter-border-width", 1382 DEFVAR_SPECIFIER ("left-gutter-border-width",
1084 &Vgutter_border_width[LEFT_GUTTER] /* 1383 &Vgutter_border_width[LEFT_GUTTER] /*
1085 *Border width of left gutter. 1384 *Border width of left gutter.
1086 This is a specifier; use `set-specifier' to change it. 1385 This is a specifier; use `set-specifier' to change it.
1089 */ ); 1388 */ );
1090 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum); 1389 Vgutter_border_width[LEFT_GUTTER] = Fmake_specifier (Qnatnum);
1091 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER], 1390 set_specifier_caching (Vgutter_border_width[LEFT_GUTTER],
1092 offsetof (struct window, 1391 offsetof (struct window,
1093 gutter_border_width[LEFT_GUTTER]), 1392 gutter_border_width[LEFT_GUTTER]),
1094 gutter_geometry_changed_in_window, 1393 gutter_geometry_changed_in_window, 0, 0);
1095 0, 0);
1096 1394
1097 DEFVAR_SPECIFIER ("right-gutter-border-width", 1395 DEFVAR_SPECIFIER ("right-gutter-border-width",
1098 &Vgutter_border_width[RIGHT_GUTTER] /* 1396 &Vgutter_border_width[RIGHT_GUTTER] /*
1099 *Border width of right gutter. 1397 *Border width of right gutter.
1100 This is a specifier; use `set-specifier' to change it. 1398 This is a specifier; use `set-specifier' to change it.
1103 */ ); 1401 */ );
1104 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum); 1402 Vgutter_border_width[RIGHT_GUTTER] = Fmake_specifier (Qnatnum);
1105 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER], 1403 set_specifier_caching (Vgutter_border_width[RIGHT_GUTTER],
1106 offsetof (struct window, 1404 offsetof (struct window,
1107 gutter_border_width[RIGHT_GUTTER]), 1405 gutter_border_width[RIGHT_GUTTER]),
1108 gutter_geometry_changed_in_window, 1406 gutter_geometry_changed_in_window, 0, 0);
1109 0, 0);
1110 1407
1111 fb = Qnil; 1408 fb = Qnil;
1112 #ifdef HAVE_TTY 1409 #ifdef HAVE_TTY
1113 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb); 1410 fb = Fcons (Fcons (list1 (Qtty), Qzero), fb);
1114 #endif 1411 #endif
1141 instead. 1438 instead.
1142 1439
1143 `default-gutter-visible-p' and all of the position-specific gutter 1440 `default-gutter-visible-p' and all of the position-specific gutter
1144 visibility specifiers have a fallback value of true. 1441 visibility specifiers have a fallback value of true.
1145 */ ); 1442 */ );
1146 Vdefault_gutter_visible_p = Fmake_specifier (Qboolean); 1443 Vdefault_gutter_visible_p = Fmake_specifier (Qgutter_visible);
1147 set_specifier_caching (Vdefault_gutter_visible_p, 1444 set_specifier_caching (Vdefault_gutter_visible_p,
1148 offsetof (struct window, 1445 offsetof (struct window,
1149 default_gutter_visible_p), 1446 default_gutter_visible_p),
1150 default_gutter_visible_p_changed_in_window, 1447 default_gutter_visible_p_changed_in_window,
1151 0, 0); 1448 0, 0);
1155 *Whether the top gutter is visible. 1452 *Whether the top gutter is visible.
1156 This is a specifier; use `set-specifier' to change it. 1453 This is a specifier; use `set-specifier' to change it.
1157 1454
1158 See `default-gutter-visible-p' for more information. 1455 See `default-gutter-visible-p' for more information.
1159 */ ); 1456 */ );
1160 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qboolean); 1457 Vgutter_visible_p[TOP_GUTTER] = Fmake_specifier (Qgutter_visible);
1161 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER], 1458 set_specifier_caching (Vgutter_visible_p[TOP_GUTTER],
1162 offsetof (struct window, 1459 offsetof (struct window,
1163 gutter_visible_p[TOP_GUTTER]), 1460 gutter_visible_p[TOP_GUTTER]),
1164 gutter_geometry_changed_in_window, 1461 top_gutter_specs_changed, 0, 0);
1165 0, 0);
1166 1462
1167 DEFVAR_SPECIFIER ("bottom-gutter-visible-p", 1463 DEFVAR_SPECIFIER ("bottom-gutter-visible-p",
1168 &Vgutter_visible_p[BOTTOM_GUTTER] /* 1464 &Vgutter_visible_p[BOTTOM_GUTTER] /*
1169 *Whether the bottom gutter is visible. 1465 *Whether the bottom gutter is visible.
1170 This is a specifier; use `set-specifier' to change it. 1466 This is a specifier; use `set-specifier' to change it.
1171 1467
1172 See `default-gutter-visible-p' for more information. 1468 See `default-gutter-visible-p' for more information.
1173 */ ); 1469 */ );
1174 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qboolean); 1470 Vgutter_visible_p[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_visible);
1175 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER], 1471 set_specifier_caching (Vgutter_visible_p[BOTTOM_GUTTER],
1176 offsetof (struct window, 1472 offsetof (struct window,
1177 gutter_visible_p[BOTTOM_GUTTER]), 1473 gutter_visible_p[BOTTOM_GUTTER]),
1178 gutter_geometry_changed_in_window, 1474 bottom_gutter_specs_changed, 0, 0);
1179 0, 0);
1180 1475
1181 DEFVAR_SPECIFIER ("left-gutter-visible-p", 1476 DEFVAR_SPECIFIER ("left-gutter-visible-p",
1182 &Vgutter_visible_p[LEFT_GUTTER] /* 1477 &Vgutter_visible_p[LEFT_GUTTER] /*
1183 *Whether the left gutter is visible. 1478 *Whether the left gutter is visible.
1184 This is a specifier; use `set-specifier' to change it. 1479 This is a specifier; use `set-specifier' to change it.
1185 1480
1186 See `default-gutter-visible-p' for more information. 1481 See `default-gutter-visible-p' for more information.
1187 */ ); 1482 */ );
1188 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qboolean); 1483 Vgutter_visible_p[LEFT_GUTTER] = Fmake_specifier (Qgutter_visible);
1189 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER], 1484 set_specifier_caching (Vgutter_visible_p[LEFT_GUTTER],
1190 offsetof (struct window, 1485 offsetof (struct window,
1191 gutter_visible_p[LEFT_GUTTER]), 1486 gutter_visible_p[LEFT_GUTTER]),
1192 gutter_geometry_changed_in_window, 1487 left_gutter_specs_changed, 0, 0);
1193 0, 0);
1194 1488
1195 DEFVAR_SPECIFIER ("right-gutter-visible-p", 1489 DEFVAR_SPECIFIER ("right-gutter-visible-p",
1196 &Vgutter_visible_p[RIGHT_GUTTER] /* 1490 &Vgutter_visible_p[RIGHT_GUTTER] /*
1197 *Whether the right gutter is visible. 1491 *Whether the right gutter is visible.
1198 This is a specifier; use `set-specifier' to change it. 1492 This is a specifier; use `set-specifier' to change it.
1199 1493
1200 See `default-gutter-visible-p' for more information. 1494 See `default-gutter-visible-p' for more information.
1201 */ ); 1495 */ );
1202 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qboolean); 1496 Vgutter_visible_p[RIGHT_GUTTER] = Fmake_specifier (Qgutter_visible);
1203 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER], 1497 set_specifier_caching (Vgutter_visible_p[RIGHT_GUTTER],
1204 offsetof (struct window, 1498 offsetof (struct window,
1205 gutter_visible_p[RIGHT_GUTTER]), 1499 gutter_visible_p[RIGHT_GUTTER]),
1206 gutter_geometry_changed_in_window, 1500 right_gutter_specs_changed, 0, 0);
1207 0, 0);
1208 1501
1209 /* initially, top inherits from default; this can be 1502 /* initially, top inherits from default; this can be
1210 changed with `set-default-gutter-position'. */ 1503 changed with `set-default-gutter-position'. */
1211 fb = list1 (Fcons (Qnil, Qt)); 1504 fb = list1 (Fcons (Qnil, Qt));
1212 set_specifier_fallback (Vdefault_gutter_visible_p, fb); 1505 set_specifier_fallback (Vdefault_gutter_visible_p, fb);