comparison src/xfns.c @ 31637:c1f4bdbf8465

(ALLOC_XPM_COLORS): Define if we can use Emacs' color allocation functions with the XPM lib. (struct xpm_cached_color) [ALLOC_XPM_COLORS]: New structure. (XPM_COLOR_CACHE_BUCKETS) [ALLOC_XPM_COLORS]: New macro. (xpm_color_cache) [ALLOC_XPM_COLORS]: New variable. (xpm_init_color_cache, xpm_free_color_cache, xpm_lookup_color) (xpm_alloc_color, xpm_free_colors) [ALLOC_XPM_COLORS]: New functions. (xpm_load) [ALLOC_XPM_COLORS]: Use Emacs' own color allocation functions, if possible, because these handle color allocation failure more gracefully. (Fimage_mask_p): New function.
author Gerd Moellmann <gerd@gnu.org>
date Fri, 15 Sep 2000 15:19:03 +0000
parents 829ed9cc42da
children aef83f9e7dac
comparison
equal deleted inserted replaced
31636:3ff1515f7c7a 31637:c1f4bdbf8465
779 char *, char *, 779 char *, char *,
780 int)); 780 int));
781 static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); 781 static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object));
782 static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, 782 static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object,
783 Lisp_Object)); 783 Lisp_Object));
784 static void init_color_table P_ ((void));
785 static void free_color_table P_ ((void));
786 static unsigned long *colors_in_color_table P_ ((int *n));
787 static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
788 static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
789
790
784 791
785 static struct x_frame_parm_table x_frame_parms[] = 792 static struct x_frame_parm_table x_frame_parms[] =
786 { 793 {
787 "auto-raise", x_set_autoraise, 794 "auto-raise", x_set_autoraise,
788 "auto-lower", x_set_autolower, 795 "auto-lower", x_set_autolower,
3831 : f->name))->data); 3838 : f->name))->data);
3832 3839
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
3840 static char cursor_bits[] = 3847 static char cursor_bits[] =
3841 { 3848 {
3851 { 3858 {
3852 XGCValues gc_values; 3859 XGCValues gc_values;
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 */
3860 gc_values.font = f->output_data.x->font->fid; 3867 gc_values.font = f->output_data.x->font->fid;
3861 gc_values.foreground = f->output_data.x->foreground_pixel; 3868 gc_values.foreground = f->output_data.x->foreground_pixel;
5367 5374
5368 return size; 5375 return size;
5369 } 5376 }
5370 5377
5371 5378
5379 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
5380 "Return t if image SPEC has a mask bitmap.\n\
5381 FRAME is the frame on which the image will be displayed. FRAME nil\n\
5382 or 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
5375 ***********************************************************************/ 5407 ***********************************************************************/
5376 5408
5774 /* `:heuristic-mask t' 5806 /* `:heuristic-mask t'
5775 `:mask heuristic' 5807 `:mask heuristic'
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. */
5783 5815
5784 Lisp_Object mask; 5816 Lisp_Object mask;
6016 } 6048 }
6017 6049
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
6023 static char * 6055 static char *
6024 slurp_file (file, size) 6056 slurp_file (file, size)
6025 char *file; 6057 char *file;
6026 int *size; 6058 int *size;
6327 /* Replacement for XReadBitmapFileData which isn't available under old 6359 /* Replacement for XReadBitmapFileData which isn't available under old
6328 X versions. CONTENTS is a pointer to a buffer to parse; END is the 6360 X versions. CONTENTS is a pointer to a buffer to parse; END is the
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
6334 static int 6366 static int
6335 xbm_read_bitmap_data (contents, end, width, height, data) 6367 xbm_read_bitmap_data (contents, end, width, height, data)
6336 char *contents, *end; 6368 char *contents, *end;
6337 int *width, *height; 6369 int *width, *height;
6745 x_clear_image, 6777 x_clear_image,
6746 NULL 6778 NULL
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
6793 static void xpm_init_color_cache P_ ((void));
6794 static void xpm_free_color_cache P_ ((void));
6795 static 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
6802 struct 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
6818 struct xpm_cached_color **xpm_color_cache;
6819
6820
6821 /* Initialize the color cache. */
6822
6823 static void
6824 xpm_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
6835 static void
6836 xpm_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
6859 static int
6860 xpm_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
6902 static int
6903 xpm_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
6918 static int
6919 xpm_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. */
6753 6935
6754 static int 6936 static int
6804 bzero (&attrs, sizeof attrs); 6986 bzero (&attrs, sizeof attrs);
6805 attrs.visual = FRAME_X_VISUAL (f); 6987 attrs.visual = FRAME_X_VISUAL (f);
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'. */
6820 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL); 7013 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
6821 if (CONSP (color_symbols)) 7014 if (CONSP (color_symbols))
6852 } 7045 }
6853 7046
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 {
6860 Lisp_Object file = x_find_image_file (specified_file); 7058 Lisp_Object file = x_find_image_file (specified_file);
6861 if (!STRINGP (file)) 7059 if (!STRINGP (file))
6879 } 7077 }
6880 UNBLOCK_INPUT; 7078 UNBLOCK_INPUT;
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);
6888 for (i = 0; i < attrs.nalloc_pixels; ++i) 7088 for (i = 0; i < attrs.nalloc_pixels; ++i)
6889 { 7089 {
6890 img->colors[i] = attrs.alloc_pixels[i]; 7090 img->colors[i] = attrs.alloc_pixels[i];
6891 #ifdef DEBUG_X_COLORS 7091 #ifdef DEBUG_X_COLORS
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;
6898 xassert (img->width > 0 && img->height > 0); 7099 xassert (img->width > 0 && img->height > 0);
6899 7100
6926 image_error ("Unknown error (%s)", img->spec, Qnil); 7127 image_error ("Unknown error (%s)", img->spec, Qnil);
6927 break; 7128 break;
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
6934 #endif /* HAVE_XPM != 0 */ 7138 #endif /* HAVE_XPM != 0 */
6935 7139
6962 struct ct_color **ct_table; 7166 struct ct_color **ct_table;
6963 7167
6964 /* Number of entries in the color table. */ 7168 /* Number of entries in the color table. */
6965 7169
6966 int ct_colors_allocated; 7170 int ct_colors_allocated;
6967
6968 /* Function prototypes. */
6969
6970 static void init_color_table P_ ((void));
6971 static void free_color_table P_ ((void));
6972 static unsigned long *colors_in_color_table P_ ((int *n));
6973 static unsigned long lookup_rgb_color P_ ((struct frame *f, int r, int g, int b));
6974 static unsigned long lookup_pixel_color P_ ((struct frame *f, unsigned long p));
6975
6976 7171
6977 /* Initialize the color table. */ 7172 /* Initialize the color table. */
6978 7173
6979 static void 7174 static void
6980 init_color_table () 7175 init_color_table ()
10853 staticpro (&Qpng); 11048 staticpro (&Qpng);
10854 #endif 11049 #endif
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;
10861 11057
10862 defsubr (&Sx_show_tip); 11058 defsubr (&Sx_show_tip);