diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 10 | ||||
| -rw-r--r-- | src/image.c | 475 |
2 files changed, 482 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 0fddb274d55..16cb680e455 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,13 @@ | |||
| 1 | 2004-05-11 Steven Tamm <tamm@Steven-Tamms-Computer.local> | ||
| 2 | |||
| 3 | * image.c (xpm_scan, xpm_make_color_table_v, xpm_put_color_table_v) | ||
| 4 | (xpm_get_color_table_v, xpm_make_color_table_h) | ||
| 5 | (xpm_put_color_table_h, xpm_get_color_table_h) | ||
| 6 | (xpm_str_to_color_key, xpm_load_image, xpm_load) | ||
| 7 | (syms_of_image): Support XPM on Carbon Emacs. Does not | ||
| 8 | depend on libXpm, but only supports XPM version 3 without | ||
| 9 | extensions. | ||
| 10 | |||
| 1 | 2004-05-11 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 11 | 2004-05-11 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
| 2 | 12 | ||
| 3 | * macterm.c (x_flush, XTframe_up_to_date): use FRAME_MAC_P | 13 | * macterm.c (x_flush, XTframe_up_to_date): use FRAME_MAC_P |
diff --git a/src/image.c b/src/image.c index c7bedb5de32..700ab3fa2d9 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -3184,12 +3184,15 @@ xbm_load (f, img) | |||
| 3184 | XPM images | 3184 | XPM images |
| 3185 | ***********************************************************************/ | 3185 | ***********************************************************************/ |
| 3186 | 3186 | ||
| 3187 | #ifdef HAVE_XPM | 3187 | #if defined (HAVE_XPM) || defined (MAC_OS) |
| 3188 | 3188 | ||
| 3189 | static int xpm_image_p P_ ((Lisp_Object object)); | 3189 | static int xpm_image_p P_ ((Lisp_Object object)); |
| 3190 | static int xpm_load P_ ((struct frame *f, struct image *img)); | 3190 | static int xpm_load P_ ((struct frame *f, struct image *img)); |
| 3191 | static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); | 3191 | static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); |
| 3192 | 3192 | ||
| 3193 | #endif /* HAVE_XPM || MAC_OS */ | ||
| 3194 | |||
| 3195 | #ifdef HAVE_XPM | ||
| 3193 | #ifdef HAVE_NTGUI | 3196 | #ifdef HAVE_NTGUI |
| 3194 | /* Indicate to xpm.h that we don't have Xlib. */ | 3197 | /* Indicate to xpm.h that we don't have Xlib. */ |
| 3195 | #define FOR_MSW | 3198 | #define FOR_MSW |
| @@ -3208,7 +3211,9 @@ static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); | |||
| 3208 | #else | 3211 | #else |
| 3209 | #include "X11/xpm.h" | 3212 | #include "X11/xpm.h" |
| 3210 | #endif /* HAVE_NTGUI */ | 3213 | #endif /* HAVE_NTGUI */ |
| 3214 | #endif /* HAVE_XPM */ | ||
| 3211 | 3215 | ||
| 3216 | #if defined (HAVE_XPM) || defined (MAC_OS) | ||
| 3212 | /* The symbol `xpm' identifying XPM-format images. */ | 3217 | /* The symbol `xpm' identifying XPM-format images. */ |
| 3213 | 3218 | ||
| 3214 | Lisp_Object Qxpm; | 3219 | Lisp_Object Qxpm; |
| @@ -3536,10 +3541,13 @@ xpm_image_p (object) | |||
| 3536 | || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); | 3541 | || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); |
| 3537 | } | 3542 | } |
| 3538 | 3543 | ||
| 3544 | #endif /* HAVE_XPM || MAC_OS */ | ||
| 3539 | 3545 | ||
| 3540 | /* Load image IMG which will be displayed on frame F. Value is | 3546 | /* Load image IMG which will be displayed on frame F. Value is |
| 3541 | non-zero if successful. */ | 3547 | non-zero if successful. */ |
| 3542 | 3548 | ||
| 3549 | #ifdef HAVE_XPM | ||
| 3550 | |||
| 3543 | static int | 3551 | static int |
| 3544 | xpm_load (f, img) | 3552 | xpm_load (f, img) |
| 3545 | struct frame *f; | 3553 | struct frame *f; |
| @@ -3771,6 +3779,467 @@ xpm_load (f, img) | |||
| 3771 | 3779 | ||
| 3772 | #endif /* HAVE_XPM */ | 3780 | #endif /* HAVE_XPM */ |
| 3773 | 3781 | ||
| 3782 | #ifdef MAC_OS | ||
| 3783 | |||
| 3784 | /* XPM support functions for Mac OS where libxpm is not available. | ||
| 3785 | Only XPM version 3 (without any extensions) is supported. */ | ||
| 3786 | |||
| 3787 | static int xpm_scan P_ ((unsigned char **, unsigned char *, | ||
| 3788 | unsigned char **, int *)); | ||
| 3789 | static Lisp_Object xpm_make_color_table_v | ||
| 3790 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), | ||
| 3791 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); | ||
| 3792 | static void xpm_put_color_table_v P_ ((Lisp_Object, unsigned char *, | ||
| 3793 | int, Lisp_Object)); | ||
| 3794 | static Lisp_Object xpm_get_color_table_v P_ ((Lisp_Object, | ||
| 3795 | unsigned char *, int)); | ||
| 3796 | static Lisp_Object xpm_make_color_table_h | ||
| 3797 | P_ ((void (**) (Lisp_Object, unsigned char *, int, Lisp_Object), | ||
| 3798 | Lisp_Object (**) (Lisp_Object, unsigned char *, int))); | ||
| 3799 | static void xpm_put_color_table_h P_ ((Lisp_Object, unsigned char *, | ||
| 3800 | int, Lisp_Object)); | ||
| 3801 | static Lisp_Object xpm_get_color_table_h P_ ((Lisp_Object, | ||
| 3802 | unsigned char *, int)); | ||
| 3803 | static int xpm_str_to_color_key P_ ((char *)); | ||
| 3804 | static int xpm_load_image P_ ((struct frame *, struct image *, | ||
| 3805 | unsigned char *, unsigned char *)); | ||
| 3806 | |||
| 3807 | /* Tokens returned from xpm_scan. */ | ||
| 3808 | |||
| 3809 | enum xpm_token | ||
| 3810 | { | ||
| 3811 | XPM_TK_IDENT = 256, | ||
| 3812 | XPM_TK_STRING, | ||
| 3813 | XPM_TK_EOF | ||
| 3814 | }; | ||
| 3815 | |||
| 3816 | /* Scan an XPM data and return a character (< 256) or a token defined | ||
| 3817 | by enum xpm_token above. *S and END are the start (inclusive) and | ||
| 3818 | the end (exclusive) addresses of the data, respectively. Advance | ||
| 3819 | *S while scanning. If token is either XPM_TK_IDENT or | ||
| 3820 | XPM_TK_STRING, *BEG and *LEN are set to the start address and the | ||
| 3821 | length of the corresponding token, respectively. */ | ||
| 3822 | |||
| 3823 | static int | ||
| 3824 | xpm_scan (s, end, beg, len) | ||
| 3825 | unsigned char **s, *end, **beg; | ||
| 3826 | int *len; | ||
| 3827 | { | ||
| 3828 | int c; | ||
| 3829 | |||
| 3830 | while (*s < end) | ||
| 3831 | { | ||
| 3832 | /* Skip white-space. */ | ||
| 3833 | while (*s < end && (c = *(*s)++, isspace (c))) | ||
| 3834 | ; | ||
| 3835 | |||
| 3836 | /* gnus-pointer.xpm uses '-' in its identifier. | ||
| 3837 | sb-dir-plus.xpm uses '+' in its identifier. */ | ||
| 3838 | if (isalpha (c) || c == '_' || c == '-' || c == '+') | ||
| 3839 | { | ||
| 3840 | *beg = *s - 1; | ||
| 3841 | while (*s < end && | ||
| 3842 | (c = **s, isalnum (c) || c == '_' || c == '-' || c == '+')) | ||
| 3843 | ++*s; | ||
| 3844 | *len = *s - *beg; | ||
| 3845 | return XPM_TK_IDENT; | ||
| 3846 | } | ||
| 3847 | else if (c == '"') | ||
| 3848 | { | ||
| 3849 | *beg = *s; | ||
| 3850 | while (*s < end && **s != '"') | ||
| 3851 | ++*s; | ||
| 3852 | *len = *s - *beg; | ||
| 3853 | if (*s < end) | ||
| 3854 | ++*s; | ||
| 3855 | return XPM_TK_STRING; | ||
| 3856 | } | ||
| 3857 | else if (c == '/') | ||
| 3858 | { | ||
| 3859 | if (*s < end && **s == '*') | ||
| 3860 | { | ||
| 3861 | /* C-style comment. */ | ||
| 3862 | ++*s; | ||
| 3863 | do | ||
| 3864 | { | ||
| 3865 | while (*s < end && *(*s)++ != '*') | ||
| 3866 | ; | ||
| 3867 | } | ||
| 3868 | while (*s < end && **s != '/'); | ||
| 3869 | if (*s < end) | ||
| 3870 | ++*s; | ||
| 3871 | } | ||
| 3872 | else | ||
| 3873 | return c; | ||
| 3874 | } | ||
| 3875 | else | ||
| 3876 | return c; | ||
| 3877 | } | ||
| 3878 | |||
| 3879 | return XPM_TK_EOF; | ||
| 3880 | } | ||
| 3881 | |||
| 3882 | /* Functions for color table lookup in XPM data. A Key is a string | ||
| 3883 | specifying the color of each pixel in XPM data. A value is either | ||
| 3884 | an integer that specifies a pixel color, Qt that specifies | ||
| 3885 | transparency, or Qnil for the unspecified color. If the length of | ||
| 3886 | the key string is one, a vector is used as a table. Otherwise, a | ||
| 3887 | hash table is used. */ | ||
| 3888 | |||
| 3889 | static Lisp_Object | ||
| 3890 | xpm_make_color_table_v (put_func, get_func) | ||
| 3891 | void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object); | ||
| 3892 | Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int); | ||
| 3893 | { | ||
| 3894 | *put_func = xpm_put_color_table_v; | ||
| 3895 | *get_func = xpm_get_color_table_v; | ||
| 3896 | return Fmake_vector (make_number (256), Qnil); | ||
| 3897 | } | ||
| 3898 | |||
| 3899 | static void | ||
| 3900 | xpm_put_color_table_v (color_table, chars_start, chars_len, color) | ||
| 3901 | Lisp_Object color_table; | ||
| 3902 | unsigned char *chars_start; | ||
| 3903 | int chars_len; | ||
| 3904 | Lisp_Object color; | ||
| 3905 | { | ||
| 3906 | XVECTOR (color_table)->contents[*chars_start] = color; | ||
| 3907 | } | ||
| 3908 | |||
| 3909 | static Lisp_Object | ||
| 3910 | xpm_get_color_table_v (color_table, chars_start, chars_len) | ||
| 3911 | Lisp_Object color_table; | ||
| 3912 | unsigned char *chars_start; | ||
| 3913 | int chars_len; | ||
| 3914 | { | ||
| 3915 | return XVECTOR (color_table)->contents[*chars_start]; | ||
| 3916 | } | ||
| 3917 | |||
| 3918 | static Lisp_Object | ||
| 3919 | xpm_make_color_table_h (put_func, get_func) | ||
| 3920 | void (**put_func) (Lisp_Object, unsigned char *, int, Lisp_Object); | ||
| 3921 | Lisp_Object (**get_func) (Lisp_Object, unsigned char *, int); | ||
| 3922 | { | ||
| 3923 | *put_func = xpm_put_color_table_h; | ||
| 3924 | *get_func = xpm_get_color_table_h; | ||
| 3925 | return make_hash_table (Qequal, make_number (DEFAULT_HASH_SIZE), | ||
| 3926 | make_float (DEFAULT_REHASH_SIZE), | ||
| 3927 | make_float (DEFAULT_REHASH_THRESHOLD), | ||
| 3928 | Qnil, Qnil, Qnil); | ||
| 3929 | } | ||
| 3930 | |||
| 3931 | static void | ||
| 3932 | xpm_put_color_table_h (color_table, chars_start, chars_len, color) | ||
| 3933 | Lisp_Object color_table; | ||
| 3934 | unsigned char *chars_start; | ||
| 3935 | int chars_len; | ||
| 3936 | Lisp_Object color; | ||
| 3937 | { | ||
| 3938 | struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); | ||
| 3939 | unsigned hash_code; | ||
| 3940 | Lisp_Object chars = make_unibyte_string (chars_start, chars_len); | ||
| 3941 | |||
| 3942 | hash_lookup (table, chars, &hash_code); | ||
| 3943 | hash_put (table, chars, color, hash_code); | ||
| 3944 | } | ||
| 3945 | |||
| 3946 | static Lisp_Object | ||
| 3947 | xpm_get_color_table_h (color_table, chars_start, chars_len) | ||
| 3948 | Lisp_Object color_table; | ||
| 3949 | unsigned char *chars_start; | ||
| 3950 | int chars_len; | ||
| 3951 | { | ||
| 3952 | struct Lisp_Hash_Table *table = XHASH_TABLE (color_table); | ||
| 3953 | int i = hash_lookup (table, make_unibyte_string (chars_start, chars_len), | ||
| 3954 | NULL); | ||
| 3955 | |||
| 3956 | return i >= 0 ? HASH_VALUE (table, i) : Qnil; | ||
| 3957 | } | ||
| 3958 | |||
| 3959 | enum xpm_color_key { | ||
| 3960 | XPM_COLOR_KEY_S, | ||
| 3961 | XPM_COLOR_KEY_M, | ||
| 3962 | XPM_COLOR_KEY_G4, | ||
| 3963 | XPM_COLOR_KEY_G, | ||
| 3964 | XPM_COLOR_KEY_C | ||
| 3965 | }; | ||
| 3966 | |||
| 3967 | static char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"}; | ||
| 3968 | |||
| 3969 | static int | ||
| 3970 | xpm_str_to_color_key (s) | ||
| 3971 | char *s; | ||
| 3972 | { | ||
| 3973 | int i; | ||
| 3974 | |||
| 3975 | for (i = 0; | ||
| 3976 | i < sizeof xpm_color_key_strings / sizeof xpm_color_key_strings[0]; | ||
| 3977 | i++) | ||
| 3978 | if (strcmp (xpm_color_key_strings[i], s) == 0) | ||
| 3979 | return i; | ||
| 3980 | return -1; | ||
| 3981 | } | ||
| 3982 | |||
| 3983 | static int | ||
| 3984 | xpm_load_image (f, img, contents, end) | ||
| 3985 | struct frame *f; | ||
| 3986 | struct image *img; | ||
| 3987 | unsigned char *contents, *end; | ||
| 3988 | { | ||
| 3989 | unsigned char *s = contents, *beg, *str; | ||
| 3990 | unsigned char buffer[BUFSIZ]; | ||
| 3991 | int width, height, x, y; | ||
| 3992 | int num_colors, chars_per_pixel; | ||
| 3993 | int len, LA1; | ||
| 3994 | void (*put_color_table) (Lisp_Object, unsigned char *, int, Lisp_Object); | ||
| 3995 | Lisp_Object (*get_color_table) (Lisp_Object, unsigned char *, int); | ||
| 3996 | Lisp_Object frame, color_symbols, color_table; | ||
| 3997 | int best_key, have_mask = 0; | ||
| 3998 | XImagePtr ximg = NULL, mask_img = NULL; | ||
| 3999 | |||
| 4000 | #define match() \ | ||
| 4001 | LA1 = xpm_scan (&s, end, &beg, &len) | ||
| 4002 | |||
| 4003 | #define expect(TOKEN) \ | ||
| 4004 | if (LA1 != (TOKEN)) \ | ||
| 4005 | goto failure; \ | ||
| 4006 | else \ | ||
| 4007 | match () | ||
| 4008 | |||
| 4009 | #define expect_ident(IDENT) \ | ||
| 4010 | if (LA1 == XPM_TK_IDENT \ | ||
| 4011 | && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \ | ||
| 4012 | match (); \ | ||
| 4013 | else \ | ||
| 4014 | goto failure | ||
| 4015 | |||
| 4016 | if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0)) | ||
| 4017 | goto failure; | ||
| 4018 | s += 9; | ||
| 4019 | match(); | ||
| 4020 | expect_ident ("static"); | ||
| 4021 | expect_ident ("char"); | ||
| 4022 | expect ('*'); | ||
| 4023 | expect (XPM_TK_IDENT); | ||
| 4024 | expect ('['); | ||
| 4025 | expect (']'); | ||
| 4026 | expect ('='); | ||
| 4027 | expect ('{'); | ||
| 4028 | expect (XPM_TK_STRING); | ||
| 4029 | if (len >= BUFSIZ) | ||
| 4030 | goto failure; | ||
| 4031 | memcpy (buffer, beg, len); | ||
| 4032 | buffer[len] = '\0'; | ||
| 4033 | if (sscanf (buffer, "%d %d %d %d", &width, &height, | ||
| 4034 | &num_colors, &chars_per_pixel) != 4 | ||
| 4035 | || width <= 0 || height <= 0 | ||
| 4036 | || num_colors <= 0 || chars_per_pixel <= 0) | ||
| 4037 | goto failure; | ||
| 4038 | expect (','); | ||
| 4039 | |||
| 4040 | XSETFRAME (frame, f); | ||
| 4041 | if (!NILP (Fxw_display_color_p (frame))) | ||
| 4042 | best_key = XPM_COLOR_KEY_C; | ||
| 4043 | else if (!NILP (Fx_display_grayscale_p (frame))) | ||
| 4044 | best_key = (XFASTINT (Fx_display_planes (frame)) > 2 | ||
| 4045 | ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4); | ||
| 4046 | else | ||
| 4047 | best_key = XPM_COLOR_KEY_M; | ||
| 4048 | |||
| 4049 | color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL); | ||
| 4050 | if (chars_per_pixel == 1) | ||
| 4051 | color_table = xpm_make_color_table_v (&put_color_table, | ||
| 4052 | &get_color_table); | ||
| 4053 | else | ||
| 4054 | color_table = xpm_make_color_table_h (&put_color_table, | ||
| 4055 | &get_color_table); | ||
| 4056 | |||
| 4057 | while (num_colors-- > 0) | ||
| 4058 | { | ||
| 4059 | unsigned char *color, *max_color; | ||
| 4060 | int key, next_key, max_key = 0; | ||
| 4061 | Lisp_Object symbol_color = Qnil, color_val; | ||
| 4062 | XColor cdef; | ||
| 4063 | |||
| 4064 | expect (XPM_TK_STRING); | ||
| 4065 | if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel) | ||
| 4066 | goto failure; | ||
| 4067 | memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel); | ||
| 4068 | buffer[len - chars_per_pixel] = '\0'; | ||
| 4069 | |||
| 4070 | str = strtok (buffer, " \t"); | ||
| 4071 | if (str == NULL) | ||
| 4072 | goto failure; | ||
| 4073 | key = xpm_str_to_color_key (str); | ||
| 4074 | if (key < 0) | ||
| 4075 | goto failure; | ||
| 4076 | do | ||
| 4077 | { | ||
| 4078 | color = strtok (NULL, " \t"); | ||
| 4079 | if (color == NULL) | ||
| 4080 | goto failure; | ||
| 4081 | |||
| 4082 | while (str = strtok (NULL, " \t")) | ||
| 4083 | { | ||
| 4084 | next_key = xpm_str_to_color_key (str); | ||
| 4085 | if (next_key >= 0) | ||
| 4086 | break; | ||
| 4087 | color[strlen (color)] = ' '; | ||
| 4088 | } | ||
| 4089 | |||
| 4090 | if (key == XPM_COLOR_KEY_S) | ||
| 4091 | { | ||
| 4092 | if (NILP (symbol_color)) | ||
| 4093 | symbol_color = build_string (color); | ||
| 4094 | } | ||
| 4095 | else if (max_key < key && key <= best_key) | ||
| 4096 | { | ||
| 4097 | max_key = key; | ||
| 4098 | max_color = color; | ||
| 4099 | } | ||
| 4100 | key = next_key; | ||
| 4101 | } | ||
| 4102 | while (str); | ||
| 4103 | |||
| 4104 | color_val = Qnil; | ||
| 4105 | if (!NILP (color_symbols) && !NILP (symbol_color)) | ||
| 4106 | { | ||
| 4107 | Lisp_Object specified_color = Fassoc (symbol_color, color_symbols); | ||
| 4108 | |||
| 4109 | if (CONSP (specified_color) && STRINGP (XCDR (specified_color))) | ||
| 4110 | if (xstricmp (SDATA (XCDR (specified_color)), "None") == 0) | ||
| 4111 | color_val = Qt; | ||
| 4112 | else if (x_defined_color (f, SDATA (XCDR (specified_color)), | ||
| 4113 | &cdef, 0)) | ||
| 4114 | color_val = make_number (cdef.pixel); | ||
| 4115 | } | ||
| 4116 | if (NILP (color_val) && max_key > 0) | ||
| 4117 | if (xstricmp (max_color, "None") == 0) | ||
| 4118 | color_val = Qt; | ||
| 4119 | else if (x_defined_color (f, max_color, &cdef, 0)) | ||
| 4120 | color_val = make_number (cdef.pixel); | ||
| 4121 | if (!NILP (color_val)) | ||
| 4122 | (*put_color_table) (color_table, beg, chars_per_pixel, color_val); | ||
| 4123 | |||
| 4124 | expect (','); | ||
| 4125 | } | ||
| 4126 | |||
| 4127 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | ||
| 4128 | &ximg, &img->pixmap) | ||
| 4129 | || !x_create_x_image_and_pixmap (f, width, height, 1, | ||
| 4130 | &mask_img, &img->mask)) | ||
| 4131 | { | ||
| 4132 | image_error ("Out of memory (%s)", img->spec, Qnil); | ||
| 4133 | goto error; | ||
| 4134 | } | ||
| 4135 | |||
| 4136 | for (y = 0; y < height; y++) | ||
| 4137 | { | ||
| 4138 | expect (XPM_TK_STRING); | ||
| 4139 | str = beg; | ||
| 4140 | if (len < width * chars_per_pixel) | ||
| 4141 | goto failure; | ||
| 4142 | for (x = 0; x < width; x++, str += chars_per_pixel) | ||
| 4143 | { | ||
| 4144 | Lisp_Object color_val = | ||
| 4145 | (*get_color_table) (color_table, str, chars_per_pixel); | ||
| 4146 | |||
| 4147 | XPutPixel (ximg, x, y, | ||
| 4148 | (INTEGERP (color_val) ? XINT (color_val) | ||
| 4149 | : FRAME_FOREGROUND_PIXEL (f))); | ||
| 4150 | XPutPixel (mask_img, x, y, | ||
| 4151 | (!EQ (color_val, Qt) ? PIX_MASK_DRAW (f) | ||
| 4152 | : (have_mask = 1, PIX_MASK_RETAIN (f)))); | ||
| 4153 | } | ||
| 4154 | if (y + 1 < height) | ||
| 4155 | expect (','); | ||
| 4156 | } | ||
| 4157 | |||
| 4158 | img->width = width; | ||
| 4159 | img->height = height; | ||
| 4160 | |||
| 4161 | x_put_x_image (f, ximg, img->pixmap, width, height); | ||
| 4162 | x_destroy_x_image (ximg); | ||
| 4163 | if (have_mask) | ||
| 4164 | { | ||
| 4165 | x_put_x_image (f, mask_img, img->mask, width, height); | ||
| 4166 | x_destroy_x_image (mask_img); | ||
| 4167 | } | ||
| 4168 | else | ||
| 4169 | { | ||
| 4170 | x_destroy_x_image (mask_img); | ||
| 4171 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); | ||
| 4172 | img->mask = NO_PIXMAP; | ||
| 4173 | } | ||
| 4174 | |||
| 4175 | return 1; | ||
| 4176 | |||
| 4177 | failure: | ||
| 4178 | image_error ("Invalid XPM file (%s)", img->spec, Qnil); | ||
| 4179 | error: | ||
| 4180 | x_destroy_x_image (ximg); | ||
| 4181 | x_destroy_x_image (mask_img); | ||
| 4182 | x_clear_image (f, img); | ||
| 4183 | return 0; | ||
| 4184 | |||
| 4185 | #undef match | ||
| 4186 | #undef expect | ||
| 4187 | #undef expect_ident | ||
| 4188 | } | ||
| 4189 | |||
| 4190 | static int | ||
| 4191 | xpm_load (f, img) | ||
| 4192 | struct frame *f; | ||
| 4193 | struct image *img; | ||
| 4194 | { | ||
| 4195 | int success_p = 0; | ||
| 4196 | Lisp_Object file_name; | ||
| 4197 | |||
| 4198 | /* If IMG->spec specifies a file name, create a non-file spec from it. */ | ||
| 4199 | file_name = image_spec_value (img->spec, QCfile, NULL); | ||
| 4200 | if (STRINGP (file_name)) | ||
| 4201 | { | ||
| 4202 | Lisp_Object file; | ||
| 4203 | unsigned char *contents; | ||
| 4204 | int size; | ||
| 4205 | struct gcpro gcpro1; | ||
| 4206 | |||
| 4207 | file = x_find_image_file (file_name); | ||
| 4208 | GCPRO1 (file); | ||
| 4209 | if (!STRINGP (file)) | ||
| 4210 | { | ||
| 4211 | image_error ("Cannot find image file `%s'", file_name, Qnil); | ||
| 4212 | UNGCPRO; | ||
| 4213 | return 0; | ||
| 4214 | } | ||
| 4215 | |||
| 4216 | contents = slurp_file (SDATA (file), &size); | ||
| 4217 | if (contents == NULL) | ||
| 4218 | { | ||
| 4219 | image_error ("Error loading XPM image `%s'", img->spec, Qnil); | ||
| 4220 | UNGCPRO; | ||
| 4221 | return 0; | ||
| 4222 | } | ||
| 4223 | |||
| 4224 | success_p = xpm_load_image (f, img, contents, contents + size); | ||
| 4225 | xfree (contents); | ||
| 4226 | UNGCPRO; | ||
| 4227 | } | ||
| 4228 | else | ||
| 4229 | { | ||
| 4230 | Lisp_Object data; | ||
| 4231 | |||
| 4232 | data = image_spec_value (img->spec, QCdata, NULL); | ||
| 4233 | success_p = xpm_load_image (f, img, SDATA (data), | ||
| 4234 | SDATA (data) + SBYTES (data)); | ||
| 4235 | } | ||
| 4236 | |||
| 4237 | return success_p; | ||
| 4238 | } | ||
| 4239 | |||
| 4240 | #endif /* MAC_OS */ | ||
| 4241 | |||
| 4242 | |||
| 3774 | 4243 | ||
| 3775 | /*********************************************************************** | 4244 | /*********************************************************************** |
| 3776 | Color table | 4245 | Color table |
| @@ -7447,7 +7916,7 @@ syms_of_image () | |||
| 7447 | Qxbm = intern ("xbm"); | 7916 | Qxbm = intern ("xbm"); |
| 7448 | staticpro (&Qxbm); | 7917 | staticpro (&Qxbm); |
| 7449 | 7918 | ||
| 7450 | #ifdef HAVE_XPM | 7919 | #if defined (HAVE_XPM) || defined (MAC_OS) |
| 7451 | Qxpm = intern ("xpm"); | 7920 | Qxpm = intern ("xpm"); |
| 7452 | staticpro (&Qxpm); | 7921 | staticpro (&Qxpm); |
| 7453 | #endif | 7922 | #endif |
| @@ -7517,7 +7986,7 @@ init_image () | |||
| 7517 | define_image_type (&xbm_type); | 7986 | define_image_type (&xbm_type); |
| 7518 | define_image_type (&pbm_type); | 7987 | define_image_type (&pbm_type); |
| 7519 | 7988 | ||
| 7520 | #ifdef HAVE_XPM | 7989 | #if defined (HAVE_XPM) || defined (MAC_OS) |
| 7521 | IF_LIB_AVAILABLE(init_xpm_functions) | 7990 | IF_LIB_AVAILABLE(init_xpm_functions) |
| 7522 | define_image_type (&xpm_type); | 7991 | define_image_type (&xpm_type); |
| 7523 | #endif | 7992 | #endif |