X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fglyphs.c;h=a83f4b9e95dc43f8585f6da3ee3beebdb54ea36d;hp=d69bb2dfeda0fd50a16273042771d4f391e0b3fc;hb=a5812bf2ff9a9cf40f4ff78dcb83f5b4c295bd18;hpb=98a6e4055a1fa624c592ac06f79287d55196ca37 diff --git a/src/glyphs.c b/src/glyphs.c index d69bb2d..a83f4b9 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA. */ #include "specifier.h" #include "window.h" -#ifdef HAVE_XPM +#if defined (HAVE_XPM) && !defined (HAVE_GTK) #include #endif @@ -382,7 +382,7 @@ process_image_string_instantiator (Lisp_Object data, 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) @@ -689,7 +689,7 @@ get_image_instantiator_governing_domain (Lisp_Object instantiator, int governing_domain; struct image_instantiator_methods *meths = - decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0], + decode_image_instantiator_format (INSTANTIATOR_TYPE (instantiator), ERROR_ME); governing_domain = IIFORMAT_METH_OR_GIVEN (meths, governing_domain, (), GOVERNING_DOMAIN_DEVICE); @@ -742,7 +742,7 @@ normalize_image_instantiator (Lisp_Object instantiator, 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, dest_mask), @@ -765,20 +765,20 @@ instantiate_image_instantiator (Lisp_Object governing_domain, 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], + INSTANTIATOR_TYPE (instantiator), ERROR_ME_NOT); if (!HAS_IIFORMAT_METH_P (meths, instantiate) @@ -1004,7 +1004,7 @@ print_image_instance (Lisp_Object obj, Lisp_Object printcharfun, print_internal (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0); } - + /* fallthrough */ case IMAGE_SUBWINDOW: sprintf (buf, " %dx%d", IMAGE_INSTANCE_WIDTH (ii), @@ -1469,7 +1469,7 @@ make_image_instance_1 (Lisp_Object data, Lisp_Object domain, 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); @@ -1992,9 +1992,6 @@ image_instance_layout (Lisp_Object image_instance, assert (XIMAGE_INSTANCE_YOFFSET (image_instance) >= 0 && XIMAGE_INSTANCE_XOFFSET (image_instance) >= 0); - type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii)); - meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT); - /* If geometry is unspecified then get some reasonable values for it. */ if (width == IMAGE_UNSPECIFIED_GEOMETRY || @@ -2002,20 +1999,11 @@ image_instance_layout (Lisp_Object image_instance, { 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; @@ -2042,12 +2030,15 @@ image_instance_layout (Lisp_Object image_instance, IMAGE_INSTANCE_WIDTH (ii) = width; IMAGE_INSTANCE_HEIGHT (ii) = height; - if (IIFORMAT_METH_OR_GIVEN (meths, layout, - (image_instance, width, height, xoffset, yoffset, - 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. */ @@ -2274,11 +2265,13 @@ query_string_geometry (Lisp_Object string, Lisp_Object face, int* width, int* height, int* descent, Lisp_Object domain) { struct font_metric_info fm; - unsigned char charsets[NUM_LEADING_BYTES]; + Charset_ID charsets[NUM_LEADING_BYTES]; struct face_cachel frame_cachel; struct face_cachel *cachel; Lisp_Object frame = DOMAIN_FRAME (domain); + CHECK_STRING (string); + /* Compute height */ if (height) { @@ -2326,7 +2319,7 @@ query_string_geometry (Lisp_Object string, Lisp_Object face, Lisp_Object query_string_font (Lisp_Object string, Lisp_Object face, Lisp_Object domain) { - unsigned char charsets[NUM_LEADING_BYTES]; + Charset_ID charsets[NUM_LEADING_BYTES]; struct face_cachel frame_cachel; struct face_cachel *cachel; int i; @@ -2820,6 +2813,14 @@ xface_possible_dest_types (void) * 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) { @@ -2901,6 +2902,7 @@ pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid) return Qnil; /* not reached */ } +#endif /* !HAVE_GTK */ static void check_valid_xpm_color_symbols (Lisp_Object data) @@ -3054,6 +3056,44 @@ image_mark (Lisp_Object obj) 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) { @@ -3109,19 +3149,22 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, 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 = Qnil; Lisp_Object subtable = Qnil; - Lisp_Object ls3 = 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 = @@ -3139,8 +3182,15 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, { pointer_fg = FACE_FOREGROUND (Vpointer_face, domain); pointer_bg = FACE_BACKGROUND (Vpointer_face, domain); - ls3 = list3 (glyph, 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)) @@ -3167,20 +3217,15 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, 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 : glyph, - subtable, Qunbound); + instance = Fgethash (hash_key, subtable, Qunbound); } } else if (WINDOWP (governing_domain)) @@ -3188,7 +3233,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, /* Subwindows have a per-window cache and have to be treated differently. */ instance = - Fgethash (pointerp ? ls3 : glyph, + Fgethash (hash_key, XWINDOW (governing_domain)->subwindow_instance_cache, Qunbound); } @@ -3201,7 +3246,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, { Lisp_Object locative = noseeum_cons (Qnil, - noseeum_cons (pointerp ? ls3 : glyph, + noseeum_cons (hash_key, DEVICEP (governing_domain) ? subtable : XWINDOW (governing_domain) ->subwindow_instance_cache)); @@ -3234,7 +3279,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, #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 : glyph), + assert (EQ (Fgethash (hash_key, XWINDOW (governing_domain) ->subwindow_instance_cache, Qunbound), instance)); @@ -3258,7 +3303,7 @@ image_instantiate (Lisp_Object specifier, Lisp_Object matchspec, possible to make changes that don't get reflected in the display. */ update_image_instance (instance, instantiator); - free_list (ls3); + free_list (hash_key); } #ifdef ERROR_CHECK_GLYPHS @@ -3346,7 +3391,11 @@ image_after_change (Lisp_Object specifier, Lisp_Object locale) 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); } @@ -4374,9 +4423,9 @@ check_for_ignored_expose (struct frame* f, int x, int y, int width, int height) 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", @@ -4444,15 +4493,15 @@ int find_matching_subwindow (struct frame* f, int x, int y, int width, int heigh if (IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) && - IMAGE_INSTANCE_DISPLAY_X (ii) <= x + IMAGE_INSTANCE_DISPLAY_X (ii) <= (unsigned) x && - IMAGE_INSTANCE_DISPLAY_Y (ii) <= y + 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; } @@ -4585,8 +4634,8 @@ void unmap_subwindow (Lisp_Object subwindow) 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; @@ -4616,8 +4665,8 @@ void map_subwindow (Lisp_Object subwindow, int x, int y, 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 @@ -5133,7 +5182,7 @@ image_instantiator_format_create (void) 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");