aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xfns.c230
1 files changed, 213 insertions, 17 deletions
diff --git a/src/xfns.c b/src/xfns.c
index 02cc0ade3d2..c91e49549a4 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -781,6 +781,13 @@ static Lisp_Object x_default_scroll_bar_color_parameter P_ ((struct frame *,
781static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); 781static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));
782static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, 782static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
783 Lisp_Object)); 783 Lisp_Object));
784static void init_color_table P_ ((void));
785static void free_color_table P_ ((void));
786static unsigned long *colors_in_color_table P_ ((int *n));
787static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
788static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
789
790
784 791
785static struct x_frame_parm_table x_frame_parms[] = 792static struct x_frame_parm_table x_frame_parms[] =
786{ 793{
@@ -3833,7 +3840,7 @@ x_icon (f, parms)
3833 UNBLOCK_INPUT; 3840 UNBLOCK_INPUT;
3834} 3841}
3835 3842
3836/* Make the GC's needed for this window, setting the 3843/* Make the GCs needed for this window, setting the
3837 background, border and mouse colors; also create the 3844 background, border and mouse colors; also create the
3838 mouse cursor and the gray border tile. */ 3845 mouse cursor and the gray border tile. */
3839 3846
@@ -3853,7 +3860,7 @@ x_make_gc (f)
3853 3860
3854 BLOCK_INPUT; 3861 BLOCK_INPUT;
3855 3862
3856 /* Create the GC's of this frame. 3863 /* Create the GCs of this frame.
3857 Note that many default values are used. */ 3864 Note that many default values are used. */
3858 3865
3859 /* Normal video */ 3866 /* Normal video */
@@ -5369,6 +5376,31 @@ or omitted means use the selected frame.")
5369} 5376}
5370 5377
5371 5378
5379DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
5380 "Return t if image SPEC has a mask bitmap.\n\
5381FRAME is the frame on which the image will be displayed. FRAME nil\n\
5382or omitted means use the selected frame.")
5383 (spec, frame)
5384 Lisp_Object spec, frame;
5385{
5386 Lisp_Object mask;
5387
5388 mask = Qnil;
5389 if (valid_image_p (spec))
5390 {
5391 struct frame *f = check_x_frame (frame);
5392 int id = lookup_image (f, spec);
5393 struct image *img = IMAGE_FROM_ID (f, id);
5394 if (img->mask)
5395 mask = Qt;
5396 }
5397 else
5398 error ("Invalid image specification");
5399
5400 return mask;
5401}
5402
5403
5372 5404
5373/*********************************************************************** 5405/***********************************************************************
5374 Image type independent image structures 5406 Image type independent image structures
@@ -5776,7 +5808,7 @@ lookup_image (f, spec)
5776 means build a mask heuristically. 5808 means build a mask heuristically.
5777 `:heuristic-mask (R G B)' 5809 `:heuristic-mask (R G B)'
5778 `:mask (heuristic (R G B))' 5810 `:mask (heuristic (R G B))'
5779 measn build a mask from color (R G B) in the 5811 means build a mask from color (R G B) in the
5780 image. 5812 image.
5781 `:mask nil' 5813 `:mask nil'
5782 means remove a mask, if any. */ 5814 means remove a mask, if any. */
@@ -6018,7 +6050,7 @@ x_find_image_file (file)
6018 6050
6019/* Read FILE into memory. Value is a pointer to a buffer allocated 6051/* Read FILE into memory. Value is a pointer to a buffer allocated
6020 with xmalloc holding FILE's contents. Value is null if an error 6052 with xmalloc holding FILE's contents. Value is null if an error
6021 occured. *SIZE is set to the size of the file. */ 6053 occurred. *SIZE is set to the size of the file. */
6022 6054
6023static char * 6055static char *
6024slurp_file (file, size) 6056slurp_file (file, size)
@@ -6329,7 +6361,7 @@ xbm_scan (s, end, sval, ival)
6329 buffer's end. Set *WIDTH and *HEIGHT to the width and height of 6361 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
6330 the image. Return in *DATA the bitmap data allocated with xmalloc. 6362 the image. Return in *DATA the bitmap data allocated with xmalloc.
6331 Value is non-zero if successful. DATA null means just test if 6363 Value is non-zero if successful. DATA null means just test if
6332 CONTENTS looks like an im-memory XBM file. */ 6364 CONTENTS looks like an in-memory XBM file. */
6333 6365
6334static int 6366static int
6335xbm_read_bitmap_data (contents, end, width, height, data) 6367xbm_read_bitmap_data (contents, end, width, height, data)
@@ -6747,6 +6779,156 @@ static struct image_type xpm_type =
6747}; 6779};
6748 6780
6749 6781
6782/* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
6783 functions for allocating image colors. Our own functions handle
6784 color allocation failures more gracefully than the ones on the XPM
6785 lib. */
6786
6787#if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
6788#define ALLOC_XPM_COLORS
6789#endif
6790
6791#ifdef ALLOC_XPM_COLORS
6792
6793static void xpm_init_color_cache P_ ((void));
6794static void xpm_free_color_cache P_ ((void));
6795static int xpm_lookup_color P_ ((struct frame *, char *, XColor *));
6796
6797/* An entry in a hash table used to cache color definitions of named
6798 colors. This cache is necessary to speed up XPM image loading in
6799 case we do color allocations ourselves. Without it, we would need
6800 a call to XParseColor per pixel in the image. */
6801
6802struct xpm_cached_color
6803{
6804 /* Next in collision chain. */
6805 struct xpm_cached_color *next;
6806
6807 /* Color definition (RGB and pixel color). */
6808 XColor color;
6809
6810 /* Color name. */
6811 char name[1];
6812};
6813
6814/* The hash table used for the color cache, and its bucket vector
6815 size. */
6816
6817#define XPM_COLOR_CACHE_BUCKETS 1001
6818struct xpm_cached_color **xpm_color_cache;
6819
6820
6821/* Initialize the color cache. */
6822
6823static void
6824xpm_init_color_cache ()
6825{
6826 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
6827 xpm_color_cache = (struct xpm_cached_color **) xmalloc (nbytes);
6828 memset (xpm_color_cache, 0, nbytes);
6829 init_color_table ();
6830}
6831
6832
6833/* Free the color cache. */
6834
6835static void
6836xpm_free_color_cache ()
6837{
6838 struct xpm_cached_color *p, *next;
6839 int i;
6840
6841 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
6842 for (p = xpm_color_cache[i]; p; p = next)
6843 {
6844 next = p->next;
6845 xfree (p);
6846 }
6847
6848 xfree (xpm_color_cache);
6849 xpm_color_cache = NULL;
6850 free_color_table ();
6851}
6852
6853
6854/* Look up color COLOR_NAME for frame F in the color cache. If found,
6855 return the cached definition in *COLOR. Otherwise, make a new
6856 entry in the cache and allocate the color. Value is zero if color
6857 allocation failed. */
6858
6859static int
6860xpm_lookup_color (f, color_name, color)
6861 struct frame *f;
6862 char *color_name;
6863 XColor *color;
6864{
6865 unsigned h = 0;
6866 const char *s;
6867 struct xpm_cached_color *p;
6868
6869 for (s = color_name; *s; ++s)
6870 h = (h << 2) ^ *s;
6871 h %= XPM_COLOR_CACHE_BUCKETS;
6872
6873 for (p = xpm_color_cache[h]; p; p = p->next)
6874 if (strcmp (p->name, color_name) == 0)
6875 break;
6876
6877 if (p != NULL)
6878 *color = p->color;
6879 else if (XParseColor (FRAME_X_DISPLAY (f), FRAME_X_COLORMAP (f),
6880 color_name, color))
6881 {
6882 size_t nbytes;
6883 color->pixel = lookup_rgb_color (f, color->red, color->green,
6884 color->blue);
6885 nbytes = sizeof *p + strlen (color_name);
6886 p = (struct xpm_cached_color *) xmalloc (nbytes);
6887 strcpy (p->name, color_name);
6888 p->color = *color;
6889 p->next = xpm_color_cache[h];
6890 xpm_color_cache[h] = p;
6891 }
6892
6893 return p != NULL;
6894}
6895
6896
6897/* Callback for allocating color COLOR_NAME. Called from the XPM lib.
6898 CLOSURE is a pointer to the frame on which we allocate the
6899 color. Return in *COLOR the allocated color. Value is non-zero
6900 if successful. */
6901
6902static int
6903xpm_alloc_color (dpy, cmap, color_name, color, closure)
6904 Display *dpy;
6905 Colormap cmap;
6906 char *color_name;
6907 XColor *color;
6908 void *closure;
6909{
6910 return xpm_lookup_color ((struct frame *) closure, color_name, color);
6911}
6912
6913
6914/* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
6915 is a pointer to the frame on which we allocate the color. Value is
6916 non-zero if successful. */
6917
6918static int
6919xpm_free_colors (dpy, cmap, pixels, npixels, closure)
6920 Display *dpy;
6921 Colormap cmap;
6922 Pixel *pixels;
6923 int npixels;
6924 void *closure;
6925{
6926 return 1;
6927}
6928
6929#endif /* ALLOC_XPM_COLORS */
6930
6931
6750/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list 6932/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
6751 for XPM images. Such a list must consist of conses whose car and 6933 for XPM images. Such a list must consist of conses whose car and
6752 cdr are strings. */ 6934 cdr are strings. */
@@ -6806,14 +6988,25 @@ xpm_load (f, img)
6806 attrs.colormap = FRAME_X_COLORMAP (f); 6988 attrs.colormap = FRAME_X_COLORMAP (f);
6807 attrs.valuemask |= XpmVisual; 6989 attrs.valuemask |= XpmVisual;
6808 attrs.valuemask |= XpmColormap; 6990 attrs.valuemask |= XpmColormap;
6991
6992#ifdef ALLOC_XPM_COLORS
6993 /* Allocate colors with our own functions which handle
6994 failing color allocation more gracefully. */
6995 attrs.color_closure = f;
6996 attrs.alloc_color = xpm_alloc_color;
6997 attrs.free_colors = xpm_free_colors;
6998 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
6999#else /* not ALLOC_XPM_COLORS */
7000 /* Let the XPM lib allocate colors. */
6809 attrs.valuemask |= XpmReturnAllocPixels; 7001 attrs.valuemask |= XpmReturnAllocPixels;
6810#ifdef XpmAllocCloseColors 7002#ifdef XpmAllocCloseColors
6811 attrs.alloc_close_colors = 1; 7003 attrs.alloc_close_colors = 1;
6812 attrs.valuemask |= XpmAllocCloseColors; 7004 attrs.valuemask |= XpmAllocCloseColors;
6813#else 7005#else /* not XpmAllocCloseColors */
6814 attrs.closeness = 600; 7006 attrs.closeness = 600;
6815 attrs.valuemask |= XpmCloseness; 7007 attrs.valuemask |= XpmCloseness;
6816#endif 7008#endif /* not XpmAllocCloseColors */
7009#endif /* ALLOC_XPM_COLORS */
6817 7010
6818 /* If image specification contains symbolic color definitions, add 7011 /* If image specification contains symbolic color definitions, add
6819 these to `attrs'. */ 7012 these to `attrs'. */
@@ -6854,6 +7047,11 @@ xpm_load (f, img)
6854 /* Create a pixmap for the image, either from a file, or from a 7047 /* Create a pixmap for the image, either from a file, or from a
6855 string buffer containing data in the same format as an XPM file. */ 7048 string buffer containing data in the same format as an XPM file. */
6856 BLOCK_INPUT; 7049 BLOCK_INPUT;
7050
7051#ifdef ALLOC_XPM_COLORS
7052 xpm_init_color_cache ();
7053#endif
7054
6857 specified_file = image_spec_value (img->spec, QCfile, NULL); 7055 specified_file = image_spec_value (img->spec, QCfile, NULL);
6858 if (STRINGP (specified_file)) 7056 if (STRINGP (specified_file))
6859 { 7057 {
@@ -6881,7 +7079,9 @@ xpm_load (f, img)
6881 7079
6882 if (rc == XpmSuccess) 7080 if (rc == XpmSuccess)
6883 { 7081 {
6884 /* Remember allocated colors. */ 7082#ifdef ALLOC_XPM_COLORS
7083 img->colors = colors_in_color_table (&img->ncolors);
7084#else /* not ALLOC_XPM_COLORS */
6885 img->ncolors = attrs.nalloc_pixels; 7085 img->ncolors = attrs.nalloc_pixels;
6886 img->colors = (unsigned long *) xmalloc (img->ncolors 7086 img->colors = (unsigned long *) xmalloc (img->ncolors
6887 * sizeof *img->colors); 7087 * sizeof *img->colors);
@@ -6892,6 +7092,7 @@ xpm_load (f, img)
6892 register_color (img->colors[i]); 7092 register_color (img->colors[i]);
6893#endif 7093#endif
6894 } 7094 }
7095#endif /* not ALLOC_XPM_COLORS */
6895 7096
6896 img->width = attrs.width; 7097 img->width = attrs.width;
6897 img->height = attrs.height; 7098 img->height = attrs.height;
@@ -6928,6 +7129,9 @@ xpm_load (f, img)
6928 } 7129 }
6929 } 7130 }
6930 7131
7132#ifdef ALLOC_XPM_COLORS
7133 xpm_free_color_cache ();
7134#endif
6931 return rc == XpmSuccess; 7135 return rc == XpmSuccess;
6932} 7136}
6933 7137
@@ -6965,15 +7169,6 @@ struct ct_color **ct_table;
6965 7169
6966int ct_colors_allocated; 7170int ct_colors_allocated;
6967 7171
6968/* Function prototypes. */
6969
6970static void init_color_table P_ ((void));
6971static void free_color_table P_ ((void));
6972static unsigned long *colors_in_color_table P_ ((int *n));
6973static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
6974static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
6975
6976
6977/* Initialize the color table. */ 7172/* Initialize the color table. */
6978 7173
6979static void 7174static void
@@ -10855,6 +11050,7 @@ meaning don't clear the cache.");
10855 11050
10856 defsubr (&Sclear_image_cache); 11051 defsubr (&Sclear_image_cache);
10857 defsubr (&Simage_size); 11052 defsubr (&Simage_size);
11053 defsubr (&Simage_mask_p);
10858 11054
10859 busy_cursor_atimer = NULL; 11055 busy_cursor_atimer = NULL;
10860 busy_cursor_shown_p = 0; 11056 busy_cursor_shown_p = 0;