#include "specifier.h"
#include "window.h"
-#ifdef HAVE_XPM
+#if defined (HAVE_XPM) && !defined (HAVE_GTK)
#include <X11/xpm.h>
#endif
image_instantiator_format_entry_dynarr *
the_image_instantiator_format_entry_dynarr;
-static Lisp_Object allocate_image_instance (Lisp_Object governing_domain,
- Lisp_Object glyph);
+static Lisp_Object allocate_image_instance (Lisp_Object governing_domain,
+ Lisp_Object parent,
+ Lisp_Object instantiator);
static void image_validate (Lisp_Object instantiator);
static void glyph_property_was_changed (Lisp_Object glyph,
Lisp_Object property,
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);
static void cache_subwindow_instance_in_frame_maybe (Lisp_Object instance);
+static void update_image_instance (Lisp_Object image_instance,
+ Lisp_Object instantiator);
/* Unfortunately windows and X are different. In windows BeginPaint()
will prevent WM_PAINT messages being generated so it is unnecessary
to register exposures as they will not occur. Under X they will
DEFUN ("valid-image-instantiator-format-p", Fvalid_image_instantiator_format_p,
1, 2, 0, /*
Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
-If LOCALE is non-nil then the format is checked in that domain.
+If LOCALE is non-nil then the format is checked in that locale.
If LOCALE is nil the current console is used.
Valid formats are some subset of 'nothing, 'string, 'formatted-string,
DEFUN ("set-console-type-image-conversion-list", Fset_console_type_image_conversion_list,
2, 2, 0, /*
-Set the image-conversion-list for consoles of the given TYPE.
+Set the image-conversion-list for consoles of the given CONSOLE-TYPE.
The image-conversion-list specifies how image instantiators that
are strings should be interpreted. Each element of the list should be
a list of two elements (a regular expression string and a vector) or
DEFUN ("console-type-image-conversion-list", Fconsole_type_image_conversion_list,
1, 1, 0, /*
-Return the image-conversion-list for devices of the given TYPE.
+Return the image-conversion-list for devices of the given CONSOLE-TYPE.
The image-conversion-list specifies how to interpret image string
instantiators for the specified console type. See
`set-console-type-image-conversion-list' for a description of its syntax.
skip it. */
if (!(dest_mask &
IIFORMAT_METH (decode_image_instantiator_format
- (XVECTOR_DATA (typevec)[0], ERROR_ME),
+ (INSTANTIATOR_TYPE (typevec), ERROR_ME),
possible_dest_types, ())))
continue;
if (fast_string_match (exp, 0, data, 0, -1, 0, ERROR_ME, 0) >= 0)
return find_keyword_in_vector_or_given (vector, keyword, Qnil);
}
+static Lisp_Object
+find_instantiator_differences (Lisp_Object new, Lisp_Object old)
+{
+ Lisp_Object alist = Qnil;
+ Lisp_Object *elt = XVECTOR_DATA (new);
+ Lisp_Object *old_elt = XVECTOR_DATA (old);
+ int len = XVECTOR_LENGTH (new);
+ struct gcpro gcpro1;
+
+ /* If the vector length has changed then consider everything
+ changed. We could try and figure out what properties have
+ disappeared or been added, but this code is only used as an
+ optimization anyway so lets not bother. */
+ if (len != XVECTOR_LENGTH (old))
+ return new;
+
+ GCPRO1 (alist);
+
+ for (len -= 2; len >= 1; len -= 2)
+ {
+ /* Keyword comparisons can be done with eq, the value must be
+ done with equal.
+ #### Note that this does not optimize re-ordering. */
+ if (!EQ (elt[len], old_elt[len])
+ || !internal_equal (elt[len+1], old_elt[len+1], 0))
+ alist = Fcons (Fcons (elt[len], elt[len+1]), alist);
+ }
+
+ {
+ Lisp_Object result = alist_to_tagged_vector (elt[0], alist);
+ free_alist (alist);
+ RETURN_UNGCPRO (result);
+ }
+}
+
+DEFUN ("set-instantiator-property", Fset_instantiator_property,
+ 3, 3, 0, /*
+Destructively set the property KEYWORD of INSTANTIATOR to VALUE.
+If the property is not set then it is added to a copy of the
+instantiator and the new instantiator returned.
+Use `set-glyph-image' on glyphs to register instantiator changes. */
+ (instantiator, keyword, value))
+{
+ Lisp_Object *elt;
+ int len;
+
+ CHECK_VECTOR (instantiator);
+ if (!KEYWORDP (keyword))
+ signal_simple_error ("instantiator property must be a keyword", keyword);
+
+ elt = XVECTOR_DATA (instantiator);
+ len = XVECTOR_LENGTH (instantiator);
+
+ for (len -= 2; len >= 1; len -= 2)
+ {
+ if (EQ (elt[len], keyword))
+ {
+ elt[len+1] = value;
+ break;
+ }
+ }
+
+ /* Didn't find it so add it. */
+ if (len < 1)
+ {
+ Lisp_Object alist = Qnil, result;
+ struct gcpro gcpro1;
+
+ GCPRO1 (alist);
+ alist = tagged_vector_to_alist (instantiator);
+ alist = Fcons (Fcons (keyword, value), alist);
+ result = alist_to_tagged_vector (elt[0], alist);
+ free_alist (alist);
+ RETURN_UNGCPRO (result);
+ }
+
+ return instantiator;
+}
+
void
check_valid_string (Lisp_Object data)
{
check_window_subwindow_cache (struct window* w)
{
Lisp_Object window;
-
+
XSETWINDOW (window, w);
assert (!NILP (w->subwindow_instance_cache));
/* Weird nothing images exist at startup when the console is
deleted. */
if (!NOTHING_IMAGE_INSTANCEP (instance))
- assert (DOMAIN_LIVE_P (instance));
+ {
+ assert (DOMAIN_LIVE_P (instance));
+ assert (VECTORP (XIMAGE_INSTANCE_INSTANTIATOR (instance)));
+ }
if (WINDOWP (XIMAGE_INSTANCE_DOMAIN (instance)))
- check_window_subwindow_cache
+ check_window_subwindow_cache
(XWINDOW (XIMAGE_INSTANCE_DOMAIN (instance)));
}
#endif
{
int governing_domain;
- struct image_instantiator_methods *meths =
- decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+ struct image_instantiator_methods *meths =
+ decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
ERROR_ME);
governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (),
GOVERNING_DOMAIN_DEVICE);
return domain;
}
-static Lisp_Object
+Lisp_Object
normalize_image_instantiator (Lisp_Object instantiator,
Lisp_Object contype,
Lisp_Object dest_mask)
if (STRINGP (instantiator))
instantiator = process_image_string_instantiator (instantiator, contype,
XINT (dest_mask));
-
- assert (VECTORP (instantiator));
+ /* Subsequent validation will pick this up. */
+ if (!VECTORP (instantiator))
+ return instantiator;
/* We have to always store the actual pixmap data and not the
filename even though this is a potential memory pig. We have to
do this because it is quite possible that we will need to
GCPRO1 (instantiator);
- meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+ meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
ERROR_ME);
RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
- (instantiator, contype),
+ (instantiator, contype, dest_mask),
instantiator));
}
}
Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object glyph)
{
- Lisp_Object ii = allocate_image_instance (governing_domain, glyph);
+ Lisp_Object ii = allocate_image_instance (governing_domain,
+ IMAGE_INSTANCEP (domain) ?
+ domain : glyph, instantiator);
Lisp_Image_Instance* p = XIMAGE_INSTANCE (ii);
struct image_instantiator_methods *meths, *device_meths;
struct gcpro gcpro1;
GCPRO1 (ii);
- if (!valid_image_instantiator_format_p (XVECTOR_DATA (instantiator)[0],
+ if (!valid_image_instantiator_format_p (INSTANTIATOR_TYPE (instantiator),
DOMAIN_DEVICE (governing_domain)))
signal_simple_error
("Image instantiator format is invalid in this locale.",
instantiator);
- meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+ meths = decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator),
ERROR_ME);
MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
pointer_bg, dest_mask, domain));
/* Now do device specific instantiation. */
- device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain),
- XVECTOR_DATA (instantiator)[0],
+ device_meths = decode_device_ii_format (DOMAIN_DEVICE (governing_domain),
+ INSTANTIATOR_TYPE (instantiator),
ERROR_ME_NOT);
if (!HAS_IIFORMAT_METH_P (meths, instantiate)
geometry values, thus the instance needs to have been laid-out
before they get called. */
image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
- XIMAGE_INSTANCE_HEIGHT (ii), domain);
+ XIMAGE_INSTANCE_HEIGHT (ii),
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
MAYBE_IIFORMAT_METH (device_meths, instantiate, (ii, instantiator, pointer_fg,
pointer_bg, dest_mask, domain));
IMAGE_INSTANCE_INITIALIZED (p) = 1;
/* Now that we're done verify that we really are laid out. */
if (IMAGE_INSTANCE_LAYOUT_CHANGED (p))
- image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
- XIMAGE_INSTANCE_HEIGHT (ii), domain);
-
+ image_instance_layout (ii, XIMAGE_INSTANCE_WIDTH (ii),
+ XIMAGE_INSTANCE_HEIGHT (ii),
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
+
/* We *must* have a clean image at this point. */
IMAGE_INSTANCE_TEXT_CHANGED (p) = 0;
IMAGE_INSTANCE_SIZE_CHANGED (p) = 0;
IMAGE_INSTANCE_LAYOUT_CHANGED (p) = 0;
IMAGE_INSTANCE_DIRTYP (p) = 0;
- assert ( XIMAGE_INSTANCE_HEIGHT (ii)
- != IMAGE_UNSPECIFIED_GEOMETRY
- && XIMAGE_INSTANCE_WIDTH (ii)
- != IMAGE_UNSPECIFIED_GEOMETRY);
+ assert ( XIMAGE_INSTANCE_HEIGHT (ii) >= 0
+ && XIMAGE_INSTANCE_WIDTH (ii) >= 0 );
ERROR_CHECK_IMAGE_INSTANCE (ii);
#endif
mark_object (i->name);
+ mark_object (i->instantiator);
/* Is this legal in marking? We may get in the situation where the
domain has been deleted - making the instance unusable. It seems
better to remove the domain so that it can be finalized. */
mark_object (i->domain);
/* We don't mark the glyph reference since that would create a
- circularity preventing GC. */
+ circularity preventing GC. Ditto the instantiator. */
switch (IMAGE_INSTANCE_TYPE (i))
{
case IMAGE_TEXT:
case IMAGE_WIDGET:
mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i));
mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i));
- mark_object (IMAGE_INSTANCE_WIDGET_FACE (i));
+ mark_object (IMAGE_INSTANCE_SUBWINDOW_FACE (i));
mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i));
mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i));
mark_object (IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (i));
break;
}
- /* The image may have been previously finalized (yes that's wierd,
+ /* The image may have been previously finalized (yes that's weird,
see Fdelete_frame() and mark_window_as_deleted()), in which case
the domain will be nil, so cope with this. */
if (!NILP (IMAGE_INSTANCE_DEVICE (i)))
- MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)),
+ MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (i)),
mark_image_instance, (i));
return i->device;
print_internal
(IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
}
-
+ /* fallthrough */
case IMAGE_SUBWINDOW:
sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii),
/* objects like this exist at dump time, so don't bomb out. */
if (IMAGE_INSTANCE_TYPE (i) == IMAGE_NOTHING
- ||
+ ||
NILP (IMAGE_INSTANCE_DEVICE (i)))
return;
if (for_disksave) finalose (i);
if (!internal_equal (IMAGE_INSTANCE_NAME (i1), IMAGE_INSTANCE_NAME (i2),
depth + 1))
return 0;
+ if (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (i1),
+ IMAGE_INSTANCE_INSTANTIATOR (i2),
+ depth + 1))
+ return 0;
switch (IMAGE_INSTANCE_TYPE (i1))
{
abort ();
}
- return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain),
+ return DEVMETH_OR_GIVEN (DOMAIN_XDEVICE (i1->domain),
image_instance_equal, (i1, i2, depth), 1);
}
image_instance_hash (Lisp_Object obj, int depth)
{
Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
- unsigned long hash = HASH4 (LISP_HASH (IMAGE_INSTANCE_DOMAIN (i)),
+ unsigned long hash = HASH5 (LISP_HASH (IMAGE_INSTANCE_DOMAIN (i)),
IMAGE_INSTANCE_WIDTH (i),
IMAGE_INSTANCE_MARGIN_WIDTH (i),
- IMAGE_INSTANCE_HEIGHT (i));
+ IMAGE_INSTANCE_HEIGHT (i),
+ internal_hash (IMAGE_INSTANCE_INSTANTIATOR (i),
+ depth + 1));
ERROR_CHECK_IMAGE_INSTANCE (obj);
LISP_HASH (IMAGE_INSTANCE_WIDGET_TYPE (i)),
internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1),
- internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
+ internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
depth + 1));
case IMAGE_SUBWINDOW:
- hash = HASH2 (hash, (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
+ hash = HASH2 (hash, (EMACS_INT) IMAGE_INSTANCE_SUBWINDOW_ID (i));
break;
default:
abort ();
}
- return HASH2 (hash, DEVMETH_OR_GIVEN
+ return HASH2 (hash, DEVMETH_OR_GIVEN
(XDEVICE (image_instance_device (obj)),
image_instance_hash, (i, depth),
0));
Lisp_Image_Instance);
static Lisp_Object
-allocate_image_instance (Lisp_Object governing_domain, Lisp_Object glyph)
+allocate_image_instance (Lisp_Object governing_domain, Lisp_Object parent,
+ Lisp_Object instantiator)
{
Lisp_Image_Instance *lp =
alloc_lcrecord_type (Lisp_Image_Instance, &lrecord_image_instance);
lp->width = IMAGE_UNSPECIFIED_GEOMETRY;
lp->margin_width = 0;
lp->height = IMAGE_UNSPECIFIED_GEOMETRY;
- lp->parent = glyph;
+ lp->parent = parent;
+ lp->instantiator = instantiator;
/* So that layouts get done. */
lp->layout_changed = 1;
lp->initialized = 0;
}
Error_behavior
-decode_error_behavior_flag (Lisp_Object no_error)
+decode_error_behavior_flag (Lisp_Object noerror)
{
- if (NILP (no_error)) return ERROR_ME;
- else if (EQ (no_error, Qt)) return ERROR_ME_NOT;
- else return ERROR_ME_WARN;
+ if (NILP (noerror)) return ERROR_ME;
+ else if (EQ (noerror, Qt)) return ERROR_ME_NOT;
+ else return ERROR_ME_WARN;
}
Lisp_Object
GCPRO1 (data);
/* After normalizing the data, it's always either an image instance (which
we filtered out above) or a vector. */
- if (EQ (XVECTOR_DATA (data)[0], Qinherit))
+ if (EQ (INSTANTIATOR_TYPE (data), Qinherit))
signal_simple_error ("Inheritance not allowed here", data);
governing_domain =
get_image_instantiator_governing_domain (data, domain);
If omitted, DOMAIN defaults to the selected window.
-NO-ERROR controls what happens when the image cannot be generated.
+NOERROR controls what happens when the image cannot be generated.
If nil, an error message is generated. If t, no messages are
generated and this function returns nil. If anything else, a warning
message is generated and this function returns nil.
*/
- (data, domain, dest_types, no_error))
+ (data, domain, dest_types, noerror))
{
- Error_behavior errb = decode_error_behavior_flag (no_error);
+ Error_behavior errb = decode_error_behavior_flag (noerror);
return call_with_suspended_errors ((lisp_fn_t) make_image_instance_1,
Qnil, Qimage, errb,
return Qnil;
}
-DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /*
-Set the given property of the given image instance.
-Does nothing if the property or the property method do not exist for
-the image instance in the domain.
-
-WARNING: If you are thinking about using this function, think again.
-You probably want to be using `set-glyph-image' to change the glyph's
-specifier. Be especially wary if you are thinking of calling this
-function after having called `glyph-image-instance'. Unless you are
-absolutely sure what you're doing, pretty much the only legitimate
-uses for this function are setting user-specified info in a widget,
-such as text in a text field. */
- (image_instance, prop, val))
-{
- Lisp_Image_Instance* ii;
- Lisp_Object type, ret;
- struct image_instantiator_methods* meths;
-
- CHECK_IMAGE_INSTANCE (image_instance);
- ERROR_CHECK_IMAGE_INSTANCE (image_instance);
- CHECK_SYMBOL (prop);
- ii = XIMAGE_INSTANCE (image_instance);
- type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
- /* try device specific methods first ... */
- meths = decode_device_ii_format (image_instance_device (image_instance),
- type, ERROR_ME_NOT);
- if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
- &&
- !UNBOUNDP (ret =
- IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
- {
- val = ret;
- }
- else
- {
- /* ... then format specific methods ... */
- meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
- if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
- &&
- !UNBOUNDP (ret =
- IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
- {
- val = ret;
- }
- else
- {
- val = Qnil;
- }
- }
-
- /* 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;
-
- MARK_SUBWINDOWS_STATE_CHANGED;
- MARK_GLYPHS_CHANGED;
-
- return val;
-}
-
DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /*
Return the file name from which IMAGE-INSTANCE was read, if known.
*/
/* #### There should be a copy_image_instance(), which calls a
device-specific method to copy the window-system subobject. */
- new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
- Qnil);
+ new = allocate_image_instance (XIMAGE_INSTANCE_DOMAIN (image_instance),
+ Qnil, Qnil);
copy_lcrecord (XIMAGE_INSTANCE (new), XIMAGE_INSTANCE (image_instance));
/* note that if this method returns non-zero, this method MUST
copy any window-system resources, so that when one image instance is
special function then just return the width and / or height. */
void
image_instance_query_geometry (Lisp_Object image_instance,
- unsigned int* width, unsigned int* height,
+ int* width, int* height,
enum image_instance_geometry disp,
Lisp_Object domain)
{
function relatively simple to take account of that. An alternative
approach is to consider separately the two cases, one where you
don't mind what size you have (normal widgets) and one where you
- want to specifiy something (layout widgets). */
+ want to specify something (layout widgets). */
void
image_instance_layout (Lisp_Object image_instance,
- unsigned int width, unsigned int height,
+ int width, int height,
+ int xoffset, int yoffset,
Lisp_Object domain)
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
if (NOTHING_IMAGE_INSTANCEP (image_instance))
return;
- type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
- meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+ /* We don't want carefully calculated offsets to be mucked up by
+ random layouts. */
+ if (xoffset != IMAGE_UNCHANGED_GEOMETRY)
+ XIMAGE_INSTANCE_XOFFSET (image_instance) = xoffset;
+ if (yoffset != IMAGE_UNCHANGED_GEOMETRY)
+ XIMAGE_INSTANCE_YOFFSET (image_instance) = yoffset;
+
+ assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0
+ && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0);
/* If geometry is unspecified then get some reasonable values for it. */
if (width == IMAGE_UNSPECIFIED_GEOMETRY
||
height == IMAGE_UNSPECIFIED_GEOMETRY)
{
- unsigned int dwidth = IMAGE_UNSPECIFIED_GEOMETRY,
- dheight = IMAGE_UNSPECIFIED_GEOMETRY;
-
+ int dwidth = IMAGE_UNSPECIFIED_GEOMETRY;
+ int dheight = IMAGE_UNSPECIFIED_GEOMETRY;
/* Get the desired geometry. */
- if (meths && HAS_IIFORMAT_METH_P (meths, query_geometry))
- {
- IIFORMAT_METH (meths, query_geometry, (image_instance, &dwidth, &dheight,
- IMAGE_DESIRED_GEOMETRY,
- domain));
- }
- else
- {
- dwidth = IMAGE_INSTANCE_WIDTH (ii);
- dheight = IMAGE_INSTANCE_HEIGHT (ii);
- }
-
+ image_instance_query_geometry (image_instance,
+ &dwidth, &dheight,
+ IMAGE_DESIRED_GEOMETRY,
+ domain);
/* Compare with allowed geometry. */
if (width == IMAGE_UNSPECIFIED_GEOMETRY)
width = dwidth;
IMAGE_INSTANCE_WIDTH (ii) = width;
IMAGE_INSTANCE_HEIGHT (ii) = height;
- if (IIFORMAT_METH_OR_GIVEN (meths, layout,
- (image_instance, width, height, domain), 1))
- /* Do not clear the dirty flag here - redisplay will do this for
- us at the end. */
- IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
+ type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
+ meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+
+ MAYBE_IIFORMAT_METH (meths, layout,
+ (image_instance, width, height, xoffset, yoffset,
+ domain));
+ /* Do not clear the dirty flag here - redisplay will do this for
+ us at the end. */
+ IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 0;
+}
+
+/* Update an image instance from its changed instantiator. */
+static void
+update_image_instance (Lisp_Object image_instance,
+ Lisp_Object instantiator)
+{
+ struct image_instantiator_methods* meths;
+ Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ ERROR_CHECK_IMAGE_INSTANCE (image_instance);
+
+ if (NOTHING_IMAGE_INSTANCEP (image_instance))
+ return;
+
+ assert (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0)
+ || (internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0)
+ && internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, -10)));
+
+ /* If the instantiator is identical then do nothing. We must use
+ equal here because the specifier code copies the instantiator. */
+ if (!internal_equal (IMAGE_INSTANCE_INSTANTIATOR (ii), instantiator, 0))
+ {
+ /* Extract the changed properties so that device / format
+ methods only have to cope with these. We assume that
+ normalization has already been done. */
+ Lisp_Object diffs = find_instantiator_differences
+ (instantiator,
+ IMAGE_INSTANCE_INSTANTIATOR (ii));
+ Lisp_Object type = encode_image_instance_type
+ (IMAGE_INSTANCE_TYPE (ii));
+ struct gcpro gcpro1;
+ GCPRO1 (diffs);
+
+ /* try device specific methods first ... */
+ meths = decode_device_ii_format (image_instance_device (image_instance),
+ type, ERROR_ME_NOT);
+ MAYBE_IIFORMAT_METH (meths, update, (image_instance, diffs));
+ /* ... then format specific methods ... */
+ meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+ MAYBE_IIFORMAT_METH (meths, update, (image_instance, diffs));
+
+ /* Instance and therefore glyph has changed so mark as dirty.
+ If we don't do this output optimizations will assume the
+ glyph is unchanged. */
+ set_image_instance_dirty_p (image_instance, 1);
+ /* Structure has changed. */
+ IMAGE_INSTANCE_LAYOUT_CHANGED (ii) = 1;
+
+ UNGCPRO;
+ }
+ /* We should now have a consistent instantiator so keep a record of
+ it. It is important that we don't actually update the window
+ system widgets here - we must do that when redisplay tells us
+ to.
+
+ #### should we delay doing this until the display is up-to-date
+ also? */
+ IMAGE_INSTANCE_INSTANTIATOR (ii) = instantiator;
}
/*
}
static Lisp_Object
-inherit_normalize (Lisp_Object inst, Lisp_Object console_type)
+inherit_normalize (Lisp_Object inst, Lisp_Object console_type,
+ Lisp_Object dest_mask)
{
Lisp_Object face;
helper that is used elsewhere for calculating text geometry. */
void
query_string_geometry (Lisp_Object string, Lisp_Object face,
- unsigned int* width, unsigned int* height,
- unsigned int* descent, Lisp_Object domain)
+ int* width, int* height, int* descent, Lisp_Object domain)
{
struct font_metric_info fm;
unsigned char charsets[NUM_LEADING_BYTES];
struct face_cachel *cachel;
Lisp_Object frame = DOMAIN_FRAME (domain);
+ CHECK_STRING (string);
+
/* Compute height */
if (height)
{
static void
text_query_geometry (Lisp_Object image_instance,
- unsigned int* width, unsigned int* height,
+ int* width, int* height,
enum image_instance_geometry disp, Lisp_Object domain)
{
Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
- unsigned int descent = 0;
+ int descent = 0;
query_string_geometry (IMAGE_INSTANCE_TEXT_STRING (ii),
IMAGE_INSTANCE_FACE (ii),
}
/* set the properties of a string */
-static Lisp_Object
-text_set_property (Lisp_Object image_instance, Lisp_Object prop,
- Lisp_Object val)
+static void
+text_update (Lisp_Object image_instance, Lisp_Object instantiator)
{
- Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object val = find_keyword_in_vector (instantiator, Q_data);
- if (EQ (prop, Q_data))
+ if (!NILP (val))
{
CHECK_STRING (val);
- IMAGE_INSTANCE_TEXT_STRING (ii) = val;
-
- return Qt;
+ XIMAGE_INSTANCE_TEXT_STRING (image_instance) = val;
}
- return Qunbound;
}
\f
int result;
const char *filename_ext;
- TO_EXTERNAL_FORMAT (LISP_STRING, name,
- C_STRING_ALLOCA, filename_ext,
- Qfile_name);
+ LISP_STRING_TO_EXTERNAL (name, filename_ext, Qfile_name);
result = read_bitmap_data_from_file (filename_ext, &w, &h,
- &data, xhot, yhot);
+ (unsigned char **) &data, xhot, yhot);
if (result == BitmapSuccess)
{
retval = list3 (make_int (w), make_int (h),
make_ext_string (data, len, Qbinary));
- XFree ((char *) data);
+ XFree (data);
return retval;
}
/* Normalize method for XBM's. */
static Lisp_Object
-xbm_normalize (Lisp_Object inst, Lisp_Object console_type)
+xbm_normalize (Lisp_Object inst, Lisp_Object console_type,
+ Lisp_Object dest_mask)
{
Lisp_Object file = Qnil, mask_file = Qnil;
struct gcpro gcpro1, gcpro2, gcpro3;
}
static Lisp_Object
-xface_normalize (Lisp_Object inst, Lisp_Object console_type)
+xface_normalize (Lisp_Object inst, Lisp_Object console_type,
+ Lisp_Object dest_mask)
{
/* This function can call lisp */
Lisp_Object file = Qnil, mask_file = Qnil;
* XPM *
**********************************************************************/
+#ifdef HAVE_GTK
+/* Gtk has to be gratuitously different, eh? */
+Lisp_Object
+pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
+{
+ return (make_string_from_file (name));
+}
+#else
Lisp_Object
pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid)
{
int result;
char *fname = 0;
- TO_EXTERNAL_FORMAT (LISP_STRING, name,
- C_STRING_ALLOCA, fname,
- Qfile_name);
+ LISP_STRING_TO_EXTERNAL (name, fname, Qfile_name);
result = XpmReadFileToData (fname, &data);
if (result == XpmSuccess)
return Qnil; /* not reached */
}
+#endif /* !HAVE_GTK */
static void
check_valid_xpm_color_symbols (Lisp_Object data)
}
static Lisp_Object
-xpm_normalize (Lisp_Object inst, Lisp_Object console_type)
+xpm_normalize (Lisp_Object inst, Lisp_Object console_type,
+ Lisp_Object dest_mask)
{
Lisp_Object file = Qnil;
Lisp_Object color_symbols;
mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
}
+static int
+instantiator_eq_equal (Lisp_Object obj1, Lisp_Object obj2)
+{
+ if (EQ (obj1, obj2))
+ return 1;
+
+ else if (CONSP (obj1) && CONSP (obj2))
+ {
+ return instantiator_eq_equal (XCAR (obj1), XCAR (obj2))
+ &&
+ instantiator_eq_equal (XCDR (obj1), XCDR (obj2));
+ }
+ return 0;
+}
+
+static hashcode_t
+instantiator_eq_hash (Lisp_Object obj)
+{
+ if (CONSP (obj))
+ {
+ /* no point in worrying about tail recursion, since we're not
+ going very deep */
+ return HASH2 (instantiator_eq_hash (XCAR (obj)),
+ instantiator_eq_hash (XCDR (obj)));
+ }
+ return LISP_HASH (obj);
+}
+
+/* We need a special hash table for storing image instances. */
+Lisp_Object
+make_image_instance_cache_hash_table (void)
+{
+ return make_general_lisp_hash_table
+ (instantiator_eq_hash, instantiator_eq_equal,
+ 30, -1.0, -1.0,
+ HASH_TABLE_KEY_CAR_VALUE_WEAK);
+}
+
static Lisp_Object
image_instantiate_cache_result (Lisp_Object locative)
{
signal_simple_error_2 ("Wrong domain for image instance",
instantiator, domain);
}
+ /* How ugly !! An image instanciator that uses a kludgy syntax to snarf in
+ face properties. There's a design flaw here. -- didier */
else if (VECTORP (instantiator)
- && EQ (XVECTOR_DATA (instantiator)[0], Qinherit))
+ && EQ (INSTANTIATOR_TYPE (instantiator), Qinherit))
{
assert (XVECTOR_LENGTH (instantiator) == 3);
return (FACE_PROPERTY_INSTANCE
(Fget_face (XVECTOR_DATA (instantiator)[2]),
- Qbackground_pixmap, domain, 0, depth));
+ Qbackground_pixmap, domain, 1, depth));
}
else
{
- Lisp_Object instance;
- Lisp_Object subtable;
- Lisp_Object ls3 = Qnil;
+ Lisp_Object instance = Qnil;
+ Lisp_Object subtable = Qnil;
+ /* #### Should this be GCPRO'd? */
+ Lisp_Object hash_key = Qnil;
Lisp_Object pointer_fg = Qnil;
Lisp_Object pointer_bg = Qnil;
Lisp_Object governing_domain =
get_image_instantiator_governing_domain (instantiator, domain);
+ struct gcpro gcpro1;
+
+ GCPRO1 (instance);
/* We have to put subwindow, widget and text image instances in
a per-window cache so that we can see the same glyph in
{
pointer_fg = FACE_FOREGROUND (Vpointer_face, domain);
pointer_bg = FACE_BACKGROUND (Vpointer_face, domain);
- ls3 = list3 (instantiator, pointer_fg, pointer_bg);
+ hash_key = list4 (glyph, INSTANTIATOR_TYPE (instantiator),
+ pointer_fg, pointer_bg);
}
+ else
+ /* We cannot simply key on the glyph since fallbacks could use
+ the same glyph but have a totally different instantiator
+ type. Thus we key on the glyph and the type (but not any
+ other parts of the instantiator. */
+ hash_key = list2 (glyph, INSTANTIATOR_TYPE (instantiator));
/* First look in the device cache. */
if (DEVICEP (governing_domain))
{
- subtable = Fgethash (make_int (dest_mask),
+ subtable = Fgethash (make_int (dest_mask),
XDEVICE (governing_domain)->
image_instance_cache,
Qunbound);
/* For the image instance cache, we do comparisons with
EQ rather than with EQUAL, as we do for color and
font names. The reasons are:
-
+
1) pixmap data can be very long, and thus the hashing
and comparing will take awhile.
are EQUAL but not EQ (that can happen a lot with
faces, because their specifiers are copied around);
but pixmaps tend not to be in faces.
-
+
However, if the image-instance could be a pointer, we
have to use EQUAL because we massaged the
instantiator into a cons3 also containing the
foreground and background of the pointer face. */
+ subtable = make_image_instance_cache_hash_table ();
- subtable = make_lisp_hash_table
- (20, pointerp ? HASH_TABLE_KEY_CAR_WEAK
- : HASH_TABLE_KEY_WEAK,
- pointerp ? HASH_TABLE_EQUAL
- : HASH_TABLE_EQ);
Fputhash (make_int (dest_mask), subtable,
XDEVICE (governing_domain)->image_instance_cache);
instance = Qunbound;
}
else
{
- instance = Fgethash (pointerp ? ls3 : instantiator,
- subtable, Qunbound);
+ instance = Fgethash (hash_key, subtable, Qunbound);
}
}
else if (WINDOWP (governing_domain))
/* Subwindows have a per-window cache and have to be treated
differently. */
instance =
- Fgethash (instantiator,
+ Fgethash (hash_key,
XWINDOW (governing_domain)->subwindow_instance_cache,
Qunbound);
}
{
Lisp_Object locative =
noseeum_cons (Qnil,
- noseeum_cons (pointerp ? ls3 : instantiator,
- DEVICEP (governing_domain) ? subtable
+ noseeum_cons (hash_key,
+ DEVICEP (governing_domain) ? subtable
: XWINDOW (governing_domain)
->subwindow_instance_cache));
int speccount = specpdl_depth ();
resulting instance, which gets recorded instead. */
record_unwind_protect (image_instantiate_cache_result,
locative);
- instance =
+ instance =
instantiate_image_instantiator (governing_domain,
domain, instantiator,
pointer_fg, pointer_bg,
#ifdef ERROR_CHECK_GLYPHS
if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
& (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
- assert (EQ (Fgethash ((pointerp ? ls3 : instantiator),
+ assert (EQ (Fgethash (hash_key,
XWINDOW (governing_domain)
->subwindow_instance_cache,
Qunbound), instance));
#endif
}
- else
- free_list (ls3);
-
- if (NILP (instance))
+ else if (NILP (instance))
signal_simple_error ("Can't instantiate image (probably cached)",
instantiator);
+ /* We found an instance. However, because we are using the glyph
+ as the hash key instead of the instantiator, the current
+ instantiator may not be the same as the original. Thus we
+ must update the instance based on the new
+ instantiator. Preserving instance identity like this is
+ important to stop excessive window system widget creation and
+ deletion - and hence flashing. */
+ else
+ {
+ /* #### This function should be able to cope with *all*
+ changes to the instantiator, but currently only copes
+ with the most used properties. This means that it is
+ possible to make changes that don't get reflected in the
+ display. */
+ update_image_instance (instance, instantiator);
+ free_list (hash_key);
+ }
+
#ifdef ERROR_CHECK_GLYPHS
if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
& (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
DOMAIN_FRAME (domain)));
#endif
ERROR_CHECK_IMAGE_INSTANCE (instance);
- return instance;
+ RETURN_UNGCPRO (instance);
}
abort ();
Lisp_Object property =
IMAGE_SPECIFIER_ATTACHEE_PROPERTY (XIMAGE_SPECIFIER (specifier));
if (FACEP (attachee))
- face_property_was_changed (attachee, property, locale);
+ {
+ face_property_was_changed (attachee, property, locale);
+ if (BUFFERP (locale))
+ XBUFFER (locale)->buffer_local_face_property = 1;
+ }
else if (GLYPHP (attachee))
glyph_property_was_changed (attachee, property, locale);
}
}
DEFUN ("make-glyph-internal", Fmake_glyph_internal, 0, 1, 0, /*
-Create and return a new uninitialized glyph or type TYPE.
+Create and return a new uninitialized glyph of type TYPE.
TYPE specifies the type of the glyph; this should be one of `buffer',
`pointer', or `icon', and defaults to `buffer'. The type of the glyph
if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
- IMAGE_UNSPECIFIED_GEOMETRY, domain);
+ IMAGE_UNSPECIFIED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
return XIMAGE_INSTANCE_WIDTH (instance);
}
if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
- IMAGE_UNSPECIFIED_GEOMETRY, domain);
+ IMAGE_UNSPECIFIED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT)
return XIMAGE_INSTANCE_TEXT_ASCENT (instance);
if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
- IMAGE_UNSPECIFIED_GEOMETRY, domain);
+ IMAGE_UNSPECIFIED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
if (XIMAGE_INSTANCE_TYPE (instance) == IMAGE_TEXT)
return XIMAGE_INSTANCE_TEXT_DESCENT (instance);
if (XIMAGE_INSTANCE_NEEDS_LAYOUT (instance))
image_instance_layout (instance, IMAGE_UNSPECIFIED_GEOMETRY,
- IMAGE_UNSPECIFIED_GEOMETRY, domain);
+ IMAGE_UNSPECIFIED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY,
+ IMAGE_UNCHANGED_GEOMETRY, domain);
return XIMAGE_INSTANCE_HEIGHT (instance);
}
(XGLYPH (glyph)->after_change) (glyph, property, locale);
}
-#if 0 /* Not used for now */
-static void
-glyph_query_geometry (Lisp_Object glyph_or_image, Lisp_Object window,
- unsigned int* width, unsigned int* height,
+void
+glyph_query_geometry (Lisp_Object glyph_or_image, int* width, int* height,
enum image_instance_geometry disp, Lisp_Object domain)
{
Lisp_Object instance = glyph_or_image;
if (GLYPHP (glyph_or_image))
- instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
+ instance = glyph_image_instance (glyph_or_image, domain, ERROR_ME_NOT, 1);
image_instance_query_geometry (instance, width, height, disp, domain);
}
-static void
-glyph_layout (Lisp_Object glyph_or_image, Lisp_Object window,
- unsigned int width, unsigned int height, Lisp_Object domain)
+void
+glyph_do_layout (Lisp_Object glyph_or_image, int width, int height,
+ int xoffset, int yoffset, Lisp_Object domain)
{
Lisp_Object instance = glyph_or_image;
if (GLYPHP (glyph_or_image))
- instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
+ instance = glyph_image_instance (glyph_or_image, domain, ERROR_ME_NOT, 1);
- image_instance_layout (instance, width, height, domain);
+ image_instance_layout (instance, width, height, xoffset, yoffset, domain);
}
-#endif
\f
/*****************************************************************************
cache_subwindow_instance_in_frame_maybe (Lisp_Object instance)
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (instance);
- if (image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
- & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
+ if (!NILP (DOMAIN_FRAME (IMAGE_INSTANCE_DOMAIN (ii))))
{
struct frame* f = DOMAIN_XFRAME (IMAGE_INSTANCE_DOMAIN (ii));
XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
deleted in and moreover, frame finalization deletes the window
system windows before deleting XEmacs windows, and hence
subwindows. */
-void
-free_frame_subwindow_instance_cache (struct frame* f)
+int
+unmap_subwindow_instance_cache_mapper (Lisp_Object key, Lisp_Object value,
+ void* finalize)
{
- Lisp_Object rest;
-
- LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
+ /* value can be nil; we cache failures as well as successes */
+ if (!NILP (value))
{
- Lisp_Image_Instance *ii = XIMAGE_INSTANCE (XCAR (rest));
- /* Make sure that the subwindow is unmapped so that window
- deletion will not try and do it again. */
- unmap_subwindow (XCAR (rest));
- finalize_image_instance (ii, 0);
+ struct frame* f = XFRAME (XIMAGE_INSTANCE_FRAME (value));
+ unmap_subwindow (value);
+ if (finalize)
+ {
+ /* In case GC doesn't catch up fast enough, remove from the frame
+ cache also. Otherwise code that checks the sanity of the instance
+ will fail. */
+ XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
+ = delq_no_quit (value,
+ XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
+ finalize_image_instance (XIMAGE_INSTANCE (value), 0);
+ }
}
+ return 0;
+}
+
+static void
+finalize_all_subwindow_instances (struct window *w)
+{
+ if (!NILP (w->next)) finalize_all_subwindow_instances (XWINDOW (w->next));
+ if (!NILP (w->vchild)) finalize_all_subwindow_instances (XWINDOW (w->vchild));
+ if (!NILP (w->hchild)) finalize_all_subwindow_instances (XWINDOW (w->hchild));
+
+ elisp_maphash (unmap_subwindow_instance_cache_mapper,
+ w->subwindow_instance_cache, (void*)1);
}
-/* Unmap and remove all instances from the frame cache. */
+void
+free_frame_subwindow_instances (struct frame* f)
+{
+ /* Make sure all instances are finalized. We have to do this via the
+ instance cache since some instances may be extant but not
+ displayed (and hence not in the frame cache). */
+ finalize_all_subwindow_instances (XWINDOW (f->root_window));
+}
+
+/* Unmap all instances in the frame cache. */
void
reset_frame_subwindow_instance_cache (struct frame* f)
{
LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
{
Lisp_Object value = XCAR (rest);
- /* Make sure that the subwindow is unmapped so that window
- deletion will not try and do it again. */
unmap_subwindow (value);
- XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f))
- = delq_no_quit (value, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)));
}
}
for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next)
{
/* Checking for exact matches just isn't good enough as we
- mighte get exposures for partially obscure subwindows, thus
- we have to check for overlaps. Being conservative we will
- check for exposures wholly contained by the subwindow, this
+ might get exposures for partially obscured subwindows, thus
+ we have to check for overlaps. Being conservative, we will
+ check for exposures wholly contained by the subwindow - this
might give us what we want.*/
- if (ei->x <= x && ei->y <= y
- && ei->x + ei->width >= x + width
- && ei->y + ei->height >= y + height)
+ if (ei->x <= (unsigned) x && ei->y <= (unsigned) y
+ && ei->x + ei->width >= (unsigned) (x + width)
+ && ei->y + ei->height >= (unsigned) (y + height))
{
#ifdef DEBUG_WIDGETS
stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n",
if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii)
&&
- IMAGE_INSTANCE_DISPLAY_X (ii) <= x
- &&
- IMAGE_INSTANCE_DISPLAY_Y (ii) <= y
+ IMAGE_INSTANCE_DISPLAY_X (ii) <= (unsigned) x
+ &&
+ IMAGE_INSTANCE_DISPLAY_Y (ii) <= (unsigned) y
&&
IMAGE_INSTANCE_DISPLAY_X (ii)
- + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= x + width
+ + IMAGE_INSTANCE_DISPLAY_WIDTH (ii) >= (unsigned) (x + width)
&&
IMAGE_INSTANCE_DISPLAY_Y (ii)
- + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= y + height)
+ + IMAGE_INSTANCE_DISPLAY_HEIGHT (ii) >= (unsigned) (y + height))
{
return 1;
}
should generally only get called if the subwindow is actually
dirty. */
void
-update_subwindow (Lisp_Object subwindow)
+redisplay_subwindow (Lisp_Object subwindow)
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
int count = specpdl_depth ();
if (WIDGET_IMAGE_INSTANCEP (subwindow))
{
if (image_instance_changed (subwindow))
- update_widget (subwindow);
+ redisplay_widget (subwindow);
/* Reset the changed flags. */
IMAGE_INSTANCE_WIDGET_FACE_CHANGED (ii) = 0;
IMAGE_INSTANCE_WIDGET_ITEMS_CHANGED (ii) = 0;
+ IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii) = 0;
IMAGE_INSTANCE_TEXT_CHANGED (ii) = 0;
}
else if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW
!NILP (IMAGE_INSTANCE_FRAME (ii)))
{
MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
- update_subwindow, (ii));
+ redisplay_subwindow, (ii));
}
IMAGE_INSTANCE_SIZE_CHANGED (ii) = 0;
way round - it simply means that we will get more displays than
we might need. We can get better hashing by making the depth
negative - currently it will recurse down 7 levels.*/
- IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
+ IMAGE_INSTANCE_DISPLAY_HASH (ii) = internal_hash (subwindow,
IMAGE_INSTANCE_HASH_DEPTH);
unbind_to (count, Qnil);
}
+/* Determine whether an image_instance has changed structurally and
+ hence needs redisplaying in some way.
+
+ #### This should just look at the instantiator differences when we
+ get rid of the stored items altogether. In fact we should probably
+ store the new instantiator as well as the old - as we do with
+ gui_items currently - and then pick-up the new on the next
+ redisplay. This would obviate the need for any of this trickery
+ with hashcodes. */
int
image_instance_changed (Lisp_Object subwindow)
{
Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
- if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
+ if (internal_hash (subwindow, IMAGE_INSTANCE_HASH_DEPTH) !=
IMAGE_INSTANCE_DISPLAY_HASH (ii))
return 1;
/* #### I think there is probably a bug here. This gets called for
else if (WIDGET_IMAGE_INSTANCEP (subwindow)
&& (!internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
IMAGE_INSTANCE_WIDGET_PENDING_ITEMS (ii), 0)
- || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))))
+ || !NILP (IMAGE_INSTANCE_LAYOUT_CHILDREN (ii))
+ || IMAGE_INSTANCE_WIDGET_ACTION_OCCURRED (ii)))
return 1;
else
return 0;
struct frame* f;
Lisp_Object rest;
- /* Its possible for the preceeding callback to have deleted the
+ /* Its possible for the preceding callback to have deleted the
frame, so cope with this. */
if (!FRAMEP (frame) || !FRAME_LIVE_P (XFRAME (frame)))
return;
CHECK_FRAME (frame);
f = XFRAME (frame);
-
+
/* If we get called we know something has changed. */
LIST_LOOP (rest, XWEAK_LIST_LIST (FRAME_SUBWINDOW_CACHE (f)))
{
Lisp_Object widget = XCAR (rest);
-
+
if (XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (widget)
&&
image_instance_changed (widget))
ERROR_CHECK_IMAGE_INSTANCE (subwindow);
- if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
- & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)
+ if (!(image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
+ & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
||
!IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii))
return;
#ifdef DEBUG_WIDGETS
- stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+ stderr_out ("unmapping subwindow %p\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
#endif
f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
IMAGE_INSTANCE_DISPLAY_HEIGHT (ii));
IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
- MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)),
+ MAYBE_DEVMETH (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)),
unmap_subwindow, (ii));
}
ERROR_CHECK_IMAGE_INSTANCE (subwindow);
- if (!image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
- & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK))
+ if (!(image_instance_type_to_mask (IMAGE_INSTANCE_TYPE (ii))
+ & (IMAGE_WIDGET_MASK | IMAGE_SUBWINDOW_MASK)))
return;
#ifdef DEBUG_WIDGETS
- stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n",
+ stderr_out ("mapping subwindow %p, %dx%d@%d+%d\n",
IMAGE_INSTANCE_SUBWINDOW_ID (ii),
dga->width, dga->height, x, y);
#endif
f = XFRAME (IMAGE_INSTANCE_FRAME (ii));
- IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
IMAGE_INSTANCE_DISPLAY_X (ii) = x;
IMAGE_INSTANCE_DISPLAY_Y (ii) = y;
IMAGE_INSTANCE_DISPLAY_WIDTH (ii) = dga->width;
MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain),
map_subwindow, (ii, x, y, dga));
+ IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
}
static int
}
}
-/* This is just a backup in case no-one has assigned a suitable geometry.
+/* This is just a backup in case no-one has assigned a suitable geometry.
#### It should really query the enclose window for geometry. */
static void
-subwindow_query_geometry (Lisp_Object image_instance, unsigned int* width,
- unsigned int* height, enum image_instance_geometry disp,
+subwindow_query_geometry (Lisp_Object image_instance, int* width,
+ int* height, enum image_instance_geometry disp,
Lisp_Object domain)
{
if (width) *width = 20;
(subwindow))
{
CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
- return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow));
+ return make_int ((EMACS_INT) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow));
}
DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
else
newh = XINT (height);
- /* The actual resizing gets done asychronously by
+ /* The actual resizing gets done asynchronously by
update_subwindow. */
IMAGE_INSTANCE_HEIGHT (ii) = newh;
IMAGE_INSTANCE_WIDTH (ii) = neww;
DEFSUBR (Fset_console_type_image_conversion_list);
DEFSUBR (Fconsole_type_image_conversion_list);
- defkeyword (&Q_file, ":file");
- defkeyword (&Q_data, ":data");
- defkeyword (&Q_face, ":face");
- defkeyword (&Q_pixel_height, ":pixel-height");
- defkeyword (&Q_pixel_width, ":pixel-width");
+ DEFKEYWORD (Q_file);
+ DEFKEYWORD (Q_data);
+ DEFKEYWORD (Q_face);
+ DEFKEYWORD (Q_pixel_height);
+ DEFKEYWORD (Q_pixel_width);
#ifdef HAVE_XPM
- defkeyword (&Q_color_symbols, ":color-symbols");
+ DEFKEYWORD (Q_color_symbols);
#endif
#ifdef HAVE_WINDOW_SYSTEM
- defkeyword (&Q_mask_file, ":mask-file");
- defkeyword (&Q_mask_data, ":mask-data");
- defkeyword (&Q_hotspot_x, ":hotspot-x");
- defkeyword (&Q_hotspot_y, ":hotspot-y");
- defkeyword (&Q_foreground, ":foreground");
- defkeyword (&Q_background, ":background");
+ DEFKEYWORD (Q_mask_file);
+ DEFKEYWORD (Q_mask_data);
+ DEFKEYWORD (Q_hotspot_x);
+ DEFKEYWORD (Q_hotspot_y);
+ DEFKEYWORD (Q_foreground);
+ DEFKEYWORD (Q_background);
#endif
/* image specifiers */
defsymbol (&Qimage_instancep, "image-instance-p");
- defsymbol (&Qnothing_image_instance_p, "nothing-image-instance-p");
- defsymbol (&Qtext_image_instance_p, "text-image-instance-p");
- defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p");
- defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p");
- defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p");
- defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p");
- defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p");
+ DEFSYMBOL (Qnothing_image_instance_p);
+ DEFSYMBOL (Qtext_image_instance_p);
+ DEFSYMBOL (Qmono_pixmap_image_instance_p);
+ DEFSYMBOL (Qcolor_pixmap_image_instance_p);
+ DEFSYMBOL (Qpointer_image_instance_p);
+ DEFSYMBOL (Qwidget_image_instance_p);
+ DEFSYMBOL (Qsubwindow_image_instance_p);
DEFSUBR (Fmake_image_instance);
DEFSUBR (Fimage_instance_p);
DEFSUBR (Fimage_instance_foreground);
DEFSUBR (Fimage_instance_background);
DEFSUBR (Fimage_instance_property);
- DEFSUBR (Fset_image_instance_property);
DEFSUBR (Fcolorize_image_instance);
/* subwindows */
DEFSUBR (Fsubwindowp);
/* Qnothing defined as part of the "nothing" image-instantiator
type. */
/* Qtext defined in general.c */
- defsymbol (&Qmono_pixmap, "mono-pixmap");
- defsymbol (&Qcolor_pixmap, "color-pixmap");
+ DEFSYMBOL (Qmono_pixmap);
+ DEFSYMBOL (Qcolor_pixmap);
/* Qpointer defined in general.c */
/* glyphs */
- defsymbol (&Qglyphp, "glyphp");
- defsymbol (&Qcontrib_p, "contrib-p");
- defsymbol (&Qbaseline, "baseline");
+ DEFSYMBOL (Qglyphp);
+ DEFSYMBOL (Qcontrib_p);
+ DEFSYMBOL (Qbaseline);
- defsymbol (&Qbuffer_glyph_p, "buffer-glyph-p");
- defsymbol (&Qpointer_glyph_p, "pointer-glyph-p");
- defsymbol (&Qicon_glyph_p, "icon-glyph-p");
+ DEFSYMBOL (Qbuffer_glyph_p);
+ DEFSYMBOL (Qpointer_glyph_p);
+ DEFSYMBOL (Qicon_glyph_p);
- defsymbol (&Qconst_glyph_variable, "const-glyph-variable");
+ DEFSYMBOL (Qconst_glyph_variable);
DEFSUBR (Fglyph_type);
DEFSUBR (Fvalid_glyph_type_p);
DEFSUBR (Fglyph_ascent);
DEFSUBR (Fglyph_descent);
DEFSUBR (Fglyph_height);
+ DEFSUBR (Fset_instantiator_property);
/* Qbuffer defined in general.c. */
/* Qpointer defined above */
/* Unfortunately, timeout handlers must be lisp functions. This is
for animated glyphs. */
- defsymbol (&Qglyph_animated_timeout_handler,
- "glyph-animated-timeout-handler");
+ DEFSYMBOL (Qglyph_animated_timeout_handler);
DEFSUBR (Fglyph_animated_timeout_handler);
/* Errors */
- deferror (&Qimage_conversion_error,
- "image-conversion-error",
- "image-conversion error", Qio_error);
-
+ DEFERROR_STANDARD (Qimage_conversion_error, Qio_error);
}
static const struct lrecord_description image_specifier_description[] = {
};
const struct struct_description iim_description = {
- sizeof(struct image_instantiator_methods),
+ sizeof (struct image_instantiator_methods),
iim_description_1
};
Vimage_instantiator_format_list = Qnil;
staticpro (&Vimage_instantiator_format_list);
- dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description);
+ dump_add_root_struct_ptr (&the_image_instantiator_format_entry_dynarr, &iifed_description);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing");
/* #### Andy, what is this? This is a bogus format and should not be
visible to the user. */
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text");
- IIFORMAT_HAS_METHOD (text, set_property);
+ IIFORMAT_HAS_METHOD (text, update);
IIFORMAT_HAS_METHOD (text, query_geometry);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string");
set_specifier_caching (Vcurrent_display_table,
offsetof (struct window, display_table),
some_window_value_changed,
- 0, 0);
+ 0, 0, 0);
}
void