static void glyph_property_was_changed (Lisp_Object glyph,
Lisp_Object property,
Lisp_Object locale);
+static void set_image_instance_dirty_p (Lisp_Object instance, int dirty);
static void register_ignored_expose (struct frame* f, int x, int y, int width, int height);
/* Unfortunately windows and X are different. In windows BeginPaint()
will prevent WM_PAINT messages being generated so it is unnecessary
/* do this so that the cachels get reset */
if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET
||
+ IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW
+ ||
IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW)
{
MARK_FRAME_SUBWINDOWS_CHANGED
lp->y_offset = 0;
lp->width = 0;
lp->height = 0;
- lp->glyph = glyph;
- MARK_IMAGE_INSTANCE_CHANGED (lp); /* So that layouts get done. */
+ lp->parent = glyph;
+ /* So that layouts get done. */
+ lp->layout_changed = 1;
+ lp->dirty = 1;
+
XSETIMAGE_INSTANCE (val, lp);
- MARK_GLYPHS_CHANGED; /* So that the dirty flag gets reset. */
+ MARK_GLYPHS_CHANGED;
+
return val;
}
(Qerror,
list2
(emacs_doprnt_string_lisp_2
- ((CONST Bufbyte *)
+ ((const Bufbyte *)
"No compatible image-instance types given: wanted one of %s, got %s",
Qnil, -1, 2,
encode_image_instance_type_list (desired_dest_mask),
}
}
+/* Recurse up the hierarchy looking for the topmost glyph. This means
+ that instances in layouts will inherit face properties from their
+ parent. */
+Lisp_Object image_instance_parent_glyph (Lisp_Image_Instance* ii)
+{
+ if (IMAGE_INSTANCEP (IMAGE_INSTANCE_PARENT (ii)))
+ {
+ return image_instance_parent_glyph
+ (XIMAGE_INSTANCE (IMAGE_INSTANCE_PARENT (ii)));
+ }
+ return IMAGE_INSTANCE_PARENT (ii);
+}
+
static Lisp_Object
make_image_instance_1 (Lisp_Object data, Lisp_Object device,
Lisp_Object dest_types)
}
}
- /* Make sure the image instance gets redisplayed.
+ /* Make sure the image instance gets redisplayed. */
+ set_image_instance_dirty_p (image_instance, 1);
+ /* Force the glyph to be laid out again. */
+ IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
- ### This currently does not change the dirty state of an
- enclosing layout which may be bad. */
- MARK_IMAGE_INSTANCE_CHANGED (ii);
MARK_SUBWINDOWS_STATE_CHANGED;
MARK_GLYPHS_CHANGED;
/* At this point width and height should contain sane values. Thus
we set the glyph geometry and lay it out. */
+ if (IMAGE_INSTANCE_WIDTH (ii) != width
+ ||
+ IMAGE_INSTANCE_HEIGHT (ii) != height)
+ {
+ IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1;
+ }
+
IMAGE_INSTANCE_WIDTH (ii) = width;
IMAGE_INSTANCE_HEIGHT (ii) = height;
}
/* else no change to the geometry. */
- XIMAGE_INSTANCE_DIRTYP (image_instance) = 0;
+ /* Do not clear the dirty flag here - redisplay will do this for
+ us at the end. */
+ IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
}
/*
if (TEXT_IMAGE_INSTANCEP (image))
{
- XIMAGE_INSTANCE_DIRTYP (image) = 1;
+ Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image);
+ IMAGE_INSTANCE_DIRTYP (ii) = 1;
+ IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
if (GLYPHP (glyph_or_ii))
XGLYPH_DIRTYP (glyph_or_ii) = 1;
return 1;
/* error helpers */
/************************************************************************/
DOESNT_RETURN
-signal_image_error (CONST char *reason, Lisp_Object frob)
+signal_image_error (const char *reason, Lisp_Object frob)
{
signal_error (Qimage_conversion_error,
list2 (build_translated_string (reason), frob));
}
DOESNT_RETURN
-signal_image_error_2 (CONST char *reason, Lisp_Object frob0, Lisp_Object frob1)
+signal_image_error_2 (const char *reason, Lisp_Object frob0, Lisp_Object frob1)
{
signal_error (Qimage_conversion_error,
list3 (build_translated_string (reason), frob0, frob1));
unsigned int w, h;
Extbyte *data;
int result;
- CONST char *filename_ext;
+ const char *filename_ext;
TO_EXTERNAL_FORMAT (LISP_STRING, name,
C_STRING_ALLOCA, filename_ext,
if (!IMAGE_INSTANCEP (instance))
return 0;
- if (XIMAGE_INSTANCE_DIRTYP (instance))
+ if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
IMAGE_UNSPECIFIED_GEOMETRY, domain);
if (!IMAGE_INSTANCEP (instance))
return 0;
- if (XIMAGE_INSTANCE_DIRTYP (instance))
+ if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
IMAGE_UNSPECIFIED_GEOMETRY, domain);
if (!IMAGE_INSTANCEP (instance))
return 0;
- if (XIMAGE_INSTANCE_DIRTYP (instance))
+ if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
IMAGE_UNSPECIFIED_GEOMETRY, domain);
if (!IMAGE_INSTANCEP (instance))
return 0;
- if (XIMAGE_INSTANCE_DIRTYP (instance))
+ if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
IMAGE_UNSPECIFIED_GEOMETRY, domain);
}
}
+static void
+set_image_instance_dirty_p (Lisp_Object instance, int dirty)
+{
+ if (IMAGE_INSTANCEP (instance))
+ {
+ XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
+ /* Now cascade up the hierarchy. */
+ set_image_instance_dirty_p (XIMAGE_INSTANCE_PARENT (instance),
+ dirty);
+ }
+ else if (GLYPHP (instance))
+ {
+ XGLYPH_DIRTYP (instance) = dirty;
+ }
+}
+
/* #### do we need to cache this info to speed things up? */
Lisp_Object
* glyph cachel functions *
*****************************************************************************/
-/*
- #### All of this is 95% copied from face cachels.
- Consider consolidating.
- */
-
+/* #### All of this is 95% copied from face cachels. Consider
+ consolidating.
+
+ Why do we need glyph_cachels? Simply because a glyph_cachel captures
+ per-window information about a particular glyph. A glyph itself is
+ not created in any particular context, so if we were to rely on a
+ glyph to tell us about its dirtiness we would not be able to reset
+ the dirty flag after redisplaying it as it may exist in other
+ contexts. When we have redisplayed we need to know which glyphs to
+ reset the dirty flags on - the glyph_cachels give us a nice list we
+ can iterate through doing this. */
void
mark_glyph_cachels (glyph_cachel_dynarr *elements)
{
*****************************************************************************/
/* update the displayed characteristics of a subwindow */
-static void
+void
update_subwindow (Lisp_Object subwindow)
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
- if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
+ if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
||
- NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
- return;
+ IMAGE_INSTANCE_TYPE (ii) == IMAGE_LAYOUT)
+ {
+ if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET)
+ update_widget (subwindow);
+ /* Reset the changed flags. */
+ IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
+ IMAGE_INSTANCE_WIDGET_PERCENT_CHANGED (ii) = 0;
+ IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
+ IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
+ }
+ else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
+ &&
+ !NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
+ {
+ MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
+ }
- MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
- /* We must update the window's size as it may have been changed by
- the the layout routines. We also do this here so that explicit resizing
- from lisp does not result in synchronous updates. */
- MAYBE_DEVMETH (XDEVICE (ii->device), resize_subwindow, (ii,
- IMAGE_INSTANCE_WIDTH (ii),
- IMAGE_INSTANCE_HEIGHT (ii)));
+ IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
}
/* Update all the subwindows on a frame. */
{
int elt;
+ /* #### Checking all of these might be overkill now that we update
+ subwindows in the actual redisplay code. */
if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed)
for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
{
cachel->height = dga->height;
cachel->being_displayed = 1;
+#if 0
/* This forces any pending display changes to happen to the image
before we show it. I'm not sure whether or not we need mark as
clean here, but for now we will. */
update_subwindow (subwindow);
IMAGE_INSTANCE_DIRTYP (ii) = 0;
}
+#endif
MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga));
}
(subwindow, width, height))
{
int neww, newh;
+ Lisp_Image_Instance* ii;
CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
+ ii = XIMAGE_INSTANCE (subwindow);
if (NILP (width))
- neww = XIMAGE_INSTANCE_WIDTH (subwindow);
+ neww = IMAGE_INSTANCE_WIDTH (ii);
else
neww = XINT (width);
if (NILP (height))
- newh = XIMAGE_INSTANCE_HEIGHT (subwindow);
+ newh = IMAGE_INSTANCE_HEIGHT (ii);
else
newh = XINT (height);
/* The actual resizing gets done asychronously by
update_subwindow. */
- XIMAGE_INSTANCE_HEIGHT (subwindow) = newh;
- XIMAGE_INSTANCE_WIDTH (subwindow) = neww;
+ IMAGE_INSTANCE_HEIGHT (ii) = newh;
+ IMAGE_INSTANCE_WIDTH (ii) = neww;
+ IMAGE_INSTANCE_SIZE_CHANGED (ii) = 1;
/* need to update the cachels as redisplay will not do this */
update_subwindow_cachel (subwindow);
also might not. */
MARK_DEVICE_FRAMES_GLYPHS_CHANGED
(XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
- MARK_IMAGE_INSTANCE_CHANGED (ii);
+ /* Cascade dirtiness so that we can have an animated glyph in a layout
+ for instance. */
+ set_image_instance_dirty_p (value, 1);
}
}
}