X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/81d3d428c6b88e6c99f3fad6b7cc52c12236ff56..5371d722ecd94db9d5b3b21f4b91d073a38bd73b:/src/image.c diff --git a/src/image.c b/src/image.c index 33d5e1a9b2..81754ca68d 100644 --- a/src/image.c +++ b/src/image.c @@ -1,6 +1,6 @@ /* Functions for image support on window system. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -42,7 +42,7 @@ Boston, MA 02110-1301, USA. */ #include #include "charset.h" #include "coding.h" - +#include "termhooks.h" #ifdef HAVE_X_WINDOWS #include "xterm.h" @@ -733,9 +733,9 @@ Lisp_Object Qxbm; /* Keywords. */ extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile; -extern Lisp_Object QCdata, QCtype, Qcount; +extern Lisp_Object QCdata, QCtype; extern Lisp_Object Qcenter; -Lisp_Object QCascent, QCmargin, QCrelief; +Lisp_Object QCascent, QCmargin, QCrelief, Qcount; Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask; Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask; @@ -1184,9 +1184,11 @@ make_image (spec, hash) unsigned hash; { struct image *img = (struct image *) xmalloc (sizeof *img); + Lisp_Object file = image_spec_value (spec, QCfile, NULL); xassert (valid_image_p (spec)); bzero (img, sizeof *img); + img->dependencies = NILP (file) ? Qnil : list1 (file); img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); xassert (img->type != NULL); img->spec = spec; @@ -1207,7 +1209,7 @@ free_image (f, img) { if (img) { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); /* Remove IMG from the hash table of its cache. */ if (img->prev) @@ -1642,7 +1644,7 @@ search_image_cache (f, spec, hash) unsigned hash; { struct image *img; - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); int i = hash % IMAGE_CACHE_BUCKETS_SIZE; if (!c) return NULL; @@ -1689,7 +1691,7 @@ void free_image_cache (f) struct frame *f; { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); if (c) { int i; @@ -1702,26 +1704,25 @@ free_image_cache (f) xfree (c->images); xfree (c->buckets); xfree (c); - FRAME_X_IMAGE_CACHE (f) = NULL; + FRAME_IMAGE_CACHE (f) = NULL; } } -/* Clear image cache of frame F. FORCE_P non-zero means free all - images. FORCE_P zero means clear only images that haven't been - displayed for some time. Should be called from time to time to - reduce the number of loaded images. If image-cache-eviction-delay - is non-nil, this frees images in the cache which weren't displayed - for at least that many seconds. */ +/* Clear image cache of frame F. FILTER=t means free all images. + FILTER=nil means clear only images that haven't been + displayed for some time. + Else, only free the images which have FILTER in their `dependencies'. + Should be called from time to time to reduce the number of loaded images. + If image-cache-eviction-delay is non-nil, this frees images in the cache + which weren't displayed for at least that many seconds. */ void -clear_image_cache (f, force_p) - struct frame *f; - int force_p; +clear_image_cache (struct frame *f, Lisp_Object filter) { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); - if (c && INTEGERP (Vimage_cache_eviction_delay)) + if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay))) { EMACS_TIME t; unsigned long old; @@ -1738,7 +1739,9 @@ clear_image_cache (f, force_p) { struct image *img = c->images[i]; if (img != NULL - && (force_p || img->timestamp < old)) + && (NILP (filter) ? img->timestamp < old + : (EQ (Qt, filter) + || !NILP (Fmember (filter, img->dependencies))))) { free_image (f, img); ++nfreed; @@ -1756,8 +1759,7 @@ clear_image_cache (f, force_p) FOR_EACH_FRAME (tail, frame) { struct frame *f = XFRAME (frame); - if (FRAME_WINDOW_P (f) - && FRAME_X_IMAGE_CACHE (f) == c) + if (FRAME_IMAGE_CACHE (f) == c) clear_current_matrices (f); } @@ -1768,25 +1770,33 @@ clear_image_cache (f, force_p) } } +void +clear_image_caches (Lisp_Object filter) +{ + /* FIXME: We want to do + * struct terminal *t; + * for (t = terminal_list; t; t = t->next_terminal) + * clear_image_cache (t, filter); */ + Lisp_Object tail, frame; + FOR_EACH_FRAME (tail, frame) + if (FRAME_WINDOW_P (XFRAME (frame))) + clear_image_cache (XFRAME (frame), filter); +} DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache, 0, 1, 0, - doc: /* Clear the image cache of FRAME. -FRAME nil or omitted means use the selected frame. -FRAME t means clear the image caches of all frames. */) - (frame) - Lisp_Object frame; -{ - if (EQ (frame, Qt)) - { - Lisp_Object tail; - - FOR_EACH_FRAME (tail, frame) - if (FRAME_WINDOW_P (XFRAME (frame))) - clear_image_cache (XFRAME (frame), 1); - } + doc: /* Clear the image cache. +FILTER nil or a frame means clear all images in the selected frame. +FILTER t means clear the image caches of all frames. +Anything else, means only clear those images which refer to FILTER, +which is then usually a filename. */) + (filter) + Lisp_Object filter; +{ + if (!(EQ (filter, Qnil) || FRAMEP (filter))) + clear_image_caches (filter); else - clear_image_cache (check_x_frame (frame), 1); + clear_image_cache (check_x_frame (filter), Qt); return Qnil; } @@ -1916,7 +1926,7 @@ lookup_image (f, spec) xassert (FRAME_WINDOW_P (f)); xassert (valid_image_p (spec)); - c = FRAME_X_IMAGE_CACHE (f); + c = FRAME_IMAGE_CACHE (f); GCPRO1 (spec); @@ -2027,7 +2037,7 @@ cache_image (f, img) struct frame *f; struct image *img; { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); int i; /* Find a free slot in c->images. */ @@ -2062,21 +2072,29 @@ cache_image (f, img) /* Call FN on every image in the image cache of frame F. Used to mark Lisp Objects in the image cache. */ +/* Mark Lisp objects in image IMG. */ + +static void +mark_image (img) + struct image *img; +{ + mark_object (img->spec); + mark_object (img->dependencies); + + if (!NILP (img->data.lisp_val)) + mark_object (img->data.lisp_val); +} + + void -forall_images_in_image_cache (f, fn) - struct frame *f; - void (*fn) P_ ((struct image *img)); +mark_image_cache (struct image_cache *c) { - if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)) + if (c) { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); - if (c) - { - int i; - for (i = 0; i < c->used; ++i) - if (c->images[i]) - fn (c->images[i]); - } + int i; + for (i = 0; i < c->used; ++i) + if (c->images[i]) + mark_image (c->images[i]); } } @@ -3128,6 +3146,8 @@ convert_mono_to_color_image (f, img, foreground, background) release_frame_dc (f, hdc); old_prev = SelectObject (old_img_dc, img->pixmap); new_prev = SelectObject (new_img_dc, new_pixmap); + /* Windows convention for mono bitmaps is black = background, + white = foreground. */ SetTextColor (new_img_dc, background); SetBkColor (new_img_dc, foreground); @@ -3523,6 +3543,19 @@ xbm_load (f, img) else bits = XBOOL_VECTOR (data)->data; +#ifdef WINDOWSNT + { + char *invertedBits; + int nbytes, i; + /* Windows mono bitmaps are reversed compared with X. */ + invertedBits = bits; + nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR + * img->height; + bits = (char *) alloca(nbytes); + for (i = 0; i < nbytes; i++) + bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]); + } +#endif /* Create the pixmap. */ Create_Pixmap_From_Bitmap_Data (f, img, bits, @@ -8841,7 +8874,7 @@ x_kill_gs_process (pixmap, f) Pixmap pixmap; struct frame *f; { - struct image_cache *c = FRAME_X_IMAGE_CACHE (f); + struct image_cache *c = FRAME_IMAGE_CACHE (f); int class, i; struct image *img; @@ -9089,6 +9122,9 @@ non-numeric, there is no explicit limit on the size of images. */); define_image_type (&xbm_type, 1); define_image_type (&pbm_type, 1); + Qcount = intern ("count"); + staticpro (&Qcount); + QCascent = intern (":ascent"); staticpro (&QCascent); QCmargin = intern (":margin");