Mercurial > emacs
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); |