+ /* Need to reconstruct the gutter specifier as it is affected by the
+ visibility. */
+ recompute_overlaying_specifier (Vgutter);
+}
+
+
+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.
+
+See `make-gutter-size-specifier' for a description of possible gutter-size
+instantiators.
+*/
+ (object))
+{
+ return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
+}
+
+DECLARE_SPECIFIER_TYPE (gutter_visible);
+#define GUTTER_VISIBLE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_visible)
+DEFINE_SPECIFIER_TYPE (gutter_visible);
+
+static void
+gutter_visible_validate (Lisp_Object instantiator)
+{
+ if (NILP (instantiator))
+ return;
+
+ if (!NILP (instantiator) && !EQ (instantiator, Qt) && !CONSP (instantiator))
+ signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
+ instantiator);
+
+ if (CONSP (instantiator))
+ {
+ Lisp_Object rest;
+
+ EXTERNAL_LIST_LOOP (rest, instantiator)
+ {
+ if (!SYMBOLP (XCAR (rest)))
+ signal_simple_error ("Gutter visibility must be a boolean or list of symbols",
+ instantiator);
+ }
+ }
+}
+
+DEFUN ("gutter-visible-specifier-p", Fgutter_visible_specifier_p, 1, 1, 0, /*
+Return non-nil if OBJECT is a gutter-visible specifier.
+
+See `make-gutter-visible-specifier' for a description of possible
+gutter-visible instantiators.
+*/
+ (object))
+{
+ return GUTTER_VISIBLE_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));
+
+ MAYBE_DEVMETH (d, frame_output_begin, (f));
+
+ /* Sequence is quite important here. We not only want to
+ redisplay the gutter area but we also want to flush any
+ frame size changes out so that the gutter redisplay happens
+ in a kosha environment.
+
+ This is not only so that things look right but so that
+ glyph redisplay optimization kicks in, by default display
+ lines will be completely re-output if
+ f->windows_structure_changed is 1, and this is true if
+ frame size changes haven't been flushed out. Once frame
+ size changes have been flushed out we then need to
+ redisplay the frame in order to flush out pending window
+ size changes. */
+ update_frame_gutter_geometry (f);
+
+ if (f->windows_structure_changed)
+ redisplay_frame (f, 1);
+ else if (FRAME_REPAINT_P (f))
+ {
+ /* We have to be "in display" when we output the gutter
+ - make it so. */
+ hold_frame_size_changes ();
+ update_frame_gutters (f);
+ unhold_one_frame_size_changes (f);
+ }
+
+ MAYBE_DEVMETH (d, frame_output_end, (f));
+ }
+
+ d->gutter_changed = 0;
+ }
+
+ /* This is so that further changes to the gutters will trigger redisplay. */
+ gutter_changed_set = 0;
+ gutter_changed = 0;
+
+ return Qnil;