/* Synched up with: Not in FSF. */
-/* written by Andy Piper <andy@xemacs.org> with specifiers partially
- ripped-off from toolbar.c */
+/* Specifers ripped-off from toolbar.c */
#include <config.h>
#include "lisp.h"
Lisp_Object Vdefault_gutter_position;
-Lisp_Object Qgutter_size;
-
-#define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
- do { \
- switch (pos) \
- { \
- case TOP_GUTTER: \
- (frame)->top_gutter_was_visible = flag; \
- break; \
- case BOTTOM_GUTTER: \
- (frame)->bottom_gutter_was_visible = flag; \
- break; \
- case LEFT_GUTTER: \
- (frame)->left_gutter_was_visible = flag; \
- break; \
- case RIGHT_GUTTER: \
- (frame)->right_gutter_was_visible = flag; \
- break; \
- default: \
- abort (); \
- } \
+#define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
+ do { \
+ switch (pos) \
+ { \
+ case TOP_GUTTER: \
+ (frame)->top_gutter_was_visible = flag; \
+ break; \
+ case BOTTOM_GUTTER: \
+ (frame)->bottom_gutter_was_visible = flag; \
+ break; \
+ case LEFT_GUTTER: \
+ (frame)->left_gutter_was_visible = flag; \
+ break; \
+ case RIGHT_GUTTER: \
+ (frame)->right_gutter_was_visible = flag; \
+ break; \
+ default: \
+ abort (); \
+ } \
} while (0)
static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
switch (pos)
{
case TOP_GUTTER:
- return frame->top_gutter_was_visible;
+ return (frame)->top_gutter_was_visible;
case BOTTOM_GUTTER:
- return frame->bottom_gutter_was_visible;
+ return (frame)->bottom_gutter_was_visible;
case LEFT_GUTTER:
- return frame->left_gutter_was_visible;
+ return (frame)->left_gutter_was_visible;
case RIGHT_GUTTER:
- return frame->right_gutter_was_visible;
+ return (frame)->right_gutter_was_visible;
default:
abort ();
}
use this for calculating the gutter positions we run into trouble
if it is not the window nearest the gutter. Instead we predetermine
the nearest window and then use that.*/
-static void
+void
get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
int *width, int *height)
{
face_index findex = get_builtin_face_cache_index (w, Vgui_element_face);
display_line_dynarr* ddla, *cdla;
struct display_line *dl;
- int cdla_len;
if (!f->current_display_lines)
f->current_display_lines = Dynarr_new (display_line);
if (!f->desired_display_lines)
f->desired_display_lines = Dynarr_new (display_line);
-
+
ddla = f->desired_display_lines;
cdla = f->current_display_lines;
- cdla_len = Dynarr_length (cdla);
XSETFRAME (frame, f);
get_gutter_coords (f, pos, &x, &y, &width, &height);
+ /* clear out what we want to cover */
/* generate some display lines */
generate_displayable_area (w, WINDOW_GUTTER (w, pos),
x + border_width, y + border_width,
output_display_line (w, cdla, ddla, line, -1, -1);
}
- /* If the number of display lines has shrunk, adjust. */
- if (cdla_len > Dynarr_length (ddla))
- {
- Dynarr_length (cdla) = Dynarr_length (ddla);
- }
-
/* grab coordinates of last line and blank after it. */
dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
ypos = dl->ypos + dl->descent - dl->clip;
redisplay_clear_region (window, findex, x + border_width , ypos,
- width - 2 * border_width, height - (ypos - y) - border_width);
+ width - 2 * border_width, height - (ypos - y));
+
/* bevel the gutter area if so desired */
if (border_width != 0)
{
MAYBE_DEVMETH (d, bevel_area,
- (w, findex, x, y, width, height, border_width,
- EDGE_ALL, EDGE_BEVEL_OUT));
+ (w, findex, x, y, width, height, border_width));
}
}
/* sizing gutters is a pain so we try and help the user by detemining
- what height will accommodate all lines. This is useless on left and
+ what height will accomodate all lines. This is useless on left and
right gutters as we always have a maximal number of lines. */
static Lisp_Object
calculate_gutter_size (struct window *w, enum gutter_pos pos)
/* degenerate case */
if (NILP (WINDOW_GUTTER (w, pos))
||
- !FRAME_VISIBLE_P (f)
- ||
- NILP (w->buffer))
+ !FRAME_VISIBLE_P (f))
return Qnil;
ddla = Dynarr_new (display_line);
{
dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
ypos = dl->ypos + dl->descent - dl->clip;
- free_display_lines (ddla);
+ Dynarr_free (ddla);
return make_int (ypos);
}
else
{
- free_display_lines (ddla);
+ Dynarr_free (ddla);
return Qnil;
}
}
void
update_frame_gutters (struct frame *f)
{
- if (f->gutter_changed || f->clear ||
- f->glyphs_changed || f->subwindows_changed ||
- f->windows_changed || f->windows_structure_changed ||
- f->extents_changed || f->faces_changed)
+ if (f->gutter_changed || f->frame_changed || f->clear)
{
- enum gutter_pos pos;
-
- /* We don't actually care about these when outputting the gutter
- so locally disable them. */
- int local_clip_changed = f->clip_changed;
- int local_buffers_changed = f->buffers_changed;
- f->clip_changed = 0;
- f->buffers_changed = 0;
-
+ int pos;
/* and output */
- GUTTER_POS_LOOP (pos)
+
+ for (pos = 0; pos < 4; pos++)
{
if (FRAME_GUTTER_VISIBLE (f, pos))
- output_gutter (f, pos);
+ output_gutter (f, pos);
else if (gutter_was_visible (f, pos))
clear_gutter (f, pos);
}
- f->clip_changed = local_clip_changed;
- f->buffers_changed = local_buffers_changed;
- f->gutter_changed = 0;
- }
-}
-void
-reset_gutter_display_lines (struct frame* f)
-{
- if (f->current_display_lines)
- Dynarr_reset (f->current_display_lines);
+ }
+ f->gutter_changed = 0;
}
static void
int width, int height)
{
int g_x, g_y, g_width, g_height;
+ int newx, newy;
get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
- if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
+ if (((y + height) < g_y) || (y > (g_y + g_height)))
return;
if (((x + width) < g_x) || (x > (g_x + g_width)))
return;
/* #### optimize this - redrawing the whole gutter for every expose
is very expensive. We reset the current display lines because if
they're being exposed they are no longer current. */
- reset_gutter_display_lines (f);
+ if (f->current_display_lines)
+ Dynarr_reset (f->current_display_lines);
+ /* we have to do this in-case there were subwindows where we are
+ redrawing, unfortunately sometimes this also generates expose
+ events resulting in an endless cycle of redsplay. */
+ newx = max (x, g_x);
+ newy = max (y, g_y);
+ width = min (x + width - newx, g_x + g_width - newx);
+ height = min (y + height - newy, g_y + g_height - newy);
+ redisplay_unmap_subwindows_maybe (f, newx, newy, width, height);
/* Even if none of the gutter is in the area, the blank region at
the very least must be because the first thing we did is verify
redraw_exposed_gutters (struct frame *f, int x, int y, int width,
int height)
{
- enum gutter_pos pos;
- GUTTER_POS_LOOP (pos)
- {
- if (FRAME_GUTTER_VISIBLE (f, pos))
- redraw_exposed_gutter (f, pos, x, y, width, height);
- }
+ int pos;
+ for (pos = 0; pos < 4; pos++)
+ {
+ if (FRAME_GUTTER_VISIBLE (f, pos))
+ redraw_exposed_gutter (f, pos, x, y, width, height);
+ }
}
void
free_frame_gutters (struct frame *f)
{
if (f->current_display_lines)
- {
- free_display_lines (f->current_display_lines);
- f->current_display_lines = 0;
- }
+ Dynarr_free (f->current_display_lines);
if (f->desired_display_lines)
- {
- free_display_lines (f->desired_display_lines);
- f->desired_display_lines = 0;
- }
+ Dynarr_free (f->desired_display_lines);
}
static enum gutter_pos
gutter_specs_changed (Lisp_Object specifier, struct window *w,
Lisp_Object oldval)
{
- enum gutter_pos pos;
- GUTTER_POS_LOOP (pos)
+ int pos;
+ for (pos = 0; pos< 4; pos++)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->real_gutter_size[pos], Qautodetect)
gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
Lisp_Object oldval)
{
- enum gutter_pos pos;
- GUTTER_POS_LOOP (pos)
+ int pos;
+ for (pos = 0; pos< 4; pos++)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->real_gutter_size[pos], Qautodetect)
recompute_overlaying_specifier (Vgutter_visible_p);
}
-
-DECLARE_SPECIFIER_TYPE (gutter_size);
-#define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
-DEFINE_SPECIFIER_TYPE (gutter_size);
-
-static void
-gutter_size_validate (Lisp_Object instantiator)
-{
- if (NILP (instantiator))
- return;
-
- if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
- signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
-}
-
-DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
-Return non-nil if OBJECT is a gutter-size specifier.
-*/
- (object))
-{
- return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
-}
-
-DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
-Ensure that all gutters are correctly showing their gutter specifier.
-*/
- ())
-{
- Lisp_Object devcons, concons;
-
- DEVICE_LOOP_NO_BREAK (devcons, concons)
- {
- struct device *d = XDEVICE (XCAR (devcons));
- Lisp_Object frmcons;
-
- DEVICE_FRAME_LOOP (frmcons, d)
- {
- struct frame *f = XFRAME (XCAR (frmcons));
-
- if (FRAME_REPAINT_P (f))
- {
- update_frame_gutters (f);
- }
- }
-
- /* We now call the output_end routine for tty frames. We delay
- doing so in order to avoid cursor flicker. So much for 100%
- encapsulation. */
- if (DEVICE_TTY_P (d))
- DEVMETH (d, output_end, (d));
- }
-
- return Qnil;
-}
-
void
init_frame_gutters (struct frame *f)
{
- enum gutter_pos pos;
+ int pos;
struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
/* We are here as far in frame creation so cached specifiers are
already recomputed, and possibly modified by resource
initialization. We need to recalculate autodetected gutters. */
- GUTTER_POS_LOOP (pos)
+ for (pos = 0; pos< 4; pos++)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->gutter_size[pos], Qautodetect)
syms_of_gutter (void)
{
DEFSUBR (Fgutter_specifier_p);
- DEFSUBR (Fgutter_size_specifier_p);
DEFSUBR (Fset_default_gutter_position);
DEFSUBR (Fdefault_gutter_position);
DEFSUBR (Fgutter_pixel_height);
DEFSUBR (Fgutter_pixel_width);
- DEFSUBR (Fredisplay_gutter_area);
-
- defsymbol (&Qgutter_size, "gutter-size");
}
void
SPECIFIER_HAS_METHOD (gutter, validate);
SPECIFIER_HAS_METHOD (gutter, after_change);
-
- INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
-
- SPECIFIER_HAS_METHOD (gutter_size, validate);
-}
-
-void
-reinit_specifier_type_create_gutter (void)
-{
- REINITIALIZE_SPECIFIER_TYPE (gutter);
- REINITIALIZE_SPECIFIER_TYPE (gutter_size);
}
void
calculated to be large enough to hold the contents of the gutter. This
is the default.
*/ );
- Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
+ Vdefault_gutter_height = Fmake_specifier (Qgeneric);
set_specifier_caching (Vdefault_gutter_height,
slot_offset (struct window,
default_gutter_height),
See `default-gutter-height' for more information.
*/ );
- Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
+ Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgeneric);
set_specifier_caching (Vgutter_size[TOP_GUTTER],
slot_offset (struct window,
gutter_size[TOP_GUTTER]),
See `default-gutter-height' for more information.
*/ );
- Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
+ Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgeneric);
set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
slot_offset (struct window,
gutter_size[BOTTOM_GUTTER]),