diff options
| author | YAMAMOTO Mitsuharu | 2013-06-28 11:37:23 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2013-06-28 11:37:23 +0900 |
| commit | 547c92696e78d2b332b6e8a259df640ea25a8932 (patch) | |
| tree | 86d2c5b61482c311b360ab1d9e5d7bffc626aed6 /src | |
| parent | 9c8d35d532867c48ff8867466da20d70e931c5bc (diff) | |
| download | emacs-547c92696e78d2b332b6e8a259df640ea25a8932.tar.gz emacs-547c92696e78d2b332b6e8a259df640ea25a8932.zip | |
Defer image data transfer between X client and server until actual display happens.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 36 | ||||
| -rw-r--r-- | src/dispextern.h | 8 | ||||
| -rw-r--r-- | src/image.c | 459 |
3 files changed, 338 insertions, 165 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 837d946a26e..e48d3fd9f2b 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,39 @@ | |||
| 1 | 2013-06-28 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 2 | |||
| 3 | Defer image data transfer between X client and server until actual | ||
| 4 | display happens. | ||
| 5 | |||
| 6 | * dispextern.h (struct image) [HAVE_X_WINDOWS]: New members `ximg' | ||
| 7 | and `mask_img'. | ||
| 8 | |||
| 9 | * image.c (Destroy_Image): Remove. | ||
| 10 | (x_clear_image_1): New arg `flags' instead of 3 bools `pixmap_p', | ||
| 11 | `mask_p', and `colors_p'. All uses changed. | ||
| 12 | (x_clear_image_1) [HAVE_X_WINDOWS]: Destroy `ximg' and `mask_img'. | ||
| 13 | (CLEAR_IMAGE_PIXMAP, CLEAR_IMAGE_MASK, CLEAR_IMAGE_COLORS): New | ||
| 14 | macros for `flags' arg to x_clear_image_1. | ||
| 15 | (postprocess_image, xpm_load_image, x_build_heuristic_mask) | ||
| 16 | (png_load_body): Use x_clear_image_1 instead of Free_Pixmap. | ||
| 17 | (NO_PIXMAP, XGetImage) [HAVE_NS]: Remove. | ||
| 18 | (image_get_x_image_or_dc, image_unget_x_image_or_dc) | ||
| 19 | (image_get_x_image, image_unget_x_image): New functions or macros. | ||
| 20 | (image_background, image_background_transparent, x_to_xcolors) | ||
| 21 | (x_build_heuristic_mask): Use image_get_x_image_or_dc instead of | ||
| 22 | XGetImage or CreateCompatibleDC. Use image_unget_x_image_or_dc | ||
| 23 | instead of Destroy_Image. | ||
| 24 | (image_create_x_image_and_pixmap, image_put_x_image): New functions. | ||
| 25 | (xpm_load_image, x_from_xcolors, x_build_heuristic_mask, pbm_load) | ||
| 26 | (png_load_body, jpeg_load_body, tiff_load, gif_load) | ||
| 27 | (imagemagick_load_image, svg_load_image): Use them instead of | ||
| 28 | x_create_x_image_and_pixmap, and x_put_x_image followed by | ||
| 29 | x_destroy_x_image, respectively. | ||
| 30 | (xpm_load) [HAVE_XPM && !HAVE_NTGUI]: Use XpmReadFileToImage and | ||
| 31 | XpmCreateImageFromBuffer instead of XpmReadFileToPixmap and | ||
| 32 | XpmCreatePixmapFromBuffer. Create pixmaps. Fill background and | ||
| 33 | background_transparent fields. | ||
| 34 | (image_sync_to_pixmaps) [HAVE_X_WINDOWS]: New function. | ||
| 35 | (prepare_image_for_display, x_disable_image) [HAVE_X_WINDOWS]: Use it. | ||
| 36 | |||
| 1 | 2013-06-27 Paul Eggert <eggert@cs.ucla.edu> | 37 | 2013-06-27 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 38 | ||
| 3 | Do not tickle glib SIGCHLD handling if Cygwin (Bug#14569). | 39 | Do not tickle glib SIGCHLD handling if Cygwin (Bug#14569). |
diff --git a/src/dispextern.h b/src/dispextern.h index 401b3f2f6ae..a1dbc5e2024 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2870,6 +2870,14 @@ struct image | |||
| 2870 | /* Pixmaps of the image. */ | 2870 | /* Pixmaps of the image. */ |
| 2871 | Pixmap pixmap, mask; | 2871 | Pixmap pixmap, mask; |
| 2872 | 2872 | ||
| 2873 | #ifdef HAVE_X_WINDOWS | ||
| 2874 | /* X images of the image, corresponding to the above Pixmaps. | ||
| 2875 | Non-NULL means it and its Pixmap counterpart may be out of sync | ||
| 2876 | and the latter is outdated. NULL means the X image has been | ||
| 2877 | synchronized to Pixmap. */ | ||
| 2878 | XImagePtr ximg, mask_img; | ||
| 2879 | #endif | ||
| 2880 | |||
| 2873 | /* Colors allocated for this image, if any. Allocated via xmalloc. */ | 2881 | /* Colors allocated for this image, if any. Allocated via xmalloc. */ |
| 2874 | unsigned long *colors; | 2882 | unsigned long *colors; |
| 2875 | int ncolors; | 2883 | int ncolors; |
diff --git a/src/image.c b/src/image.c index b65ee7df789..52aa743e4c7 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -106,8 +106,6 @@ typedef struct ns_bitmap_record Bitmap_Record; | |||
| 106 | #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) | 106 | #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y) |
| 107 | #define NO_PIXMAP 0 | 107 | #define NO_PIXMAP 0 |
| 108 | 108 | ||
| 109 | #define ZPixmap 0 | ||
| 110 | |||
| 111 | #define PIX_MASK_RETAIN 0 | 109 | #define PIX_MASK_RETAIN 0 |
| 112 | #define PIX_MASK_DRAW 1 | 110 | #define PIX_MASK_DRAW 1 |
| 113 | 111 | ||
| @@ -146,16 +144,6 @@ Lisp_Object QCmax_width, QCmax_height; | |||
| 146 | data more than once will not be caught. */ | 144 | data more than once will not be caught. */ |
| 147 | 145 | ||
| 148 | #ifdef HAVE_NS | 146 | #ifdef HAVE_NS |
| 149 | XImagePtr | ||
| 150 | XGetImage (Display *display, Pixmap pixmap, int x, int y, | ||
| 151 | unsigned int width, unsigned int height, | ||
| 152 | unsigned long plane_mask, int format) | ||
| 153 | { | ||
| 154 | /* TODO: not sure what this function is supposed to do.. */ | ||
| 155 | ns_retain_object (pixmap); | ||
| 156 | return pixmap; | ||
| 157 | } | ||
| 158 | |||
| 159 | /* Use with images created by ns_image_for_XPM. */ | 147 | /* Use with images created by ns_image_for_XPM. */ |
| 160 | unsigned long | 148 | unsigned long |
| 161 | XGetPixel (XImagePtr ximage, int x, int y) | 149 | XGetPixel (XImagePtr ximage, int x, int y) |
| @@ -435,8 +423,24 @@ static bool x_create_x_image_and_pixmap (struct frame *, int, int, int, | |||
| 435 | XImagePtr *, Pixmap *); | 423 | XImagePtr *, Pixmap *); |
| 436 | static void x_destroy_x_image (XImagePtr ximg); | 424 | static void x_destroy_x_image (XImagePtr ximg); |
| 437 | 425 | ||
| 426 | #ifdef HAVE_NTGUI | ||
| 427 | static XImagePtr_or_DC image_get_x_image_or_dc (struct frame *, struct image *, | ||
| 428 | bool, HGDIOBJ *); | ||
| 429 | static void image_unget_x_image_or_dc (struct image *, bool, XImagePtr_or_DC, | ||
| 430 | HGDIOBJ); | ||
| 431 | #else | ||
| 432 | static XImagePtr image_get_x_image (struct frame *, struct image *, bool); | ||
| 433 | static void image_unget_x_image (struct image *, bool, XImagePtr); | ||
| 434 | #define image_get_x_image_or_dc(f, img, mask_p, dummy) \ | ||
| 435 | image_get_x_image (f, img, mask_p) | ||
| 436 | #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \ | ||
| 437 | image_unget_x_image (img, mask_p, ximg) | ||
| 438 | #endif | ||
| 439 | |||
| 438 | #ifdef HAVE_X_WINDOWS | 440 | #ifdef HAVE_X_WINDOWS |
| 439 | 441 | ||
| 442 | static void image_sync_to_pixmaps (struct frame *, struct image *); | ||
| 443 | |||
| 440 | /* Useful functions defined in the section | 444 | /* Useful functions defined in the section |
| 441 | `Image type independent image structures' below. */ | 445 | `Image type independent image structures' below. */ |
| 442 | 446 | ||
| @@ -1050,6 +1054,14 @@ prepare_image_for_display (struct frame *f, struct image *img) | |||
| 1050 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) | 1054 | if (img->pixmap == NO_PIXMAP && !img->load_failed_p) |
| 1051 | img->load_failed_p = ! img->type->load (f, img); | 1055 | img->load_failed_p = ! img->type->load (f, img); |
| 1052 | 1056 | ||
| 1057 | #ifdef HAVE_X_WINDOWS | ||
| 1058 | if (!img->load_failed_p) | ||
| 1059 | { | ||
| 1060 | block_input (); | ||
| 1061 | image_sync_to_pixmaps (f, img); | ||
| 1062 | unblock_input (); | ||
| 1063 | } | ||
| 1064 | #endif | ||
| 1053 | } | 1065 | } |
| 1054 | 1066 | ||
| 1055 | 1067 | ||
| @@ -1145,25 +1157,16 @@ four_corners_best (XImagePtr_or_DC ximg, int *corners, | |||
| 1145 | 1157 | ||
| 1146 | #ifdef HAVE_NTGUI | 1158 | #ifdef HAVE_NTGUI |
| 1147 | 1159 | ||
| 1148 | #define Destroy_Image(img_dc, prev) \ | ||
| 1149 | do { SelectObject (img_dc, prev); DeleteDC (img_dc); } while (0) | ||
| 1150 | |||
| 1151 | #define Free_Pixmap(display, pixmap) \ | 1160 | #define Free_Pixmap(display, pixmap) \ |
| 1152 | DeleteObject (pixmap) | 1161 | DeleteObject (pixmap) |
| 1153 | 1162 | ||
| 1154 | #elif defined (HAVE_NS) | 1163 | #elif defined (HAVE_NS) |
| 1155 | 1164 | ||
| 1156 | #define Destroy_Image(ximg, dummy) \ | ||
| 1157 | ns_release_object (ximg) | ||
| 1158 | |||
| 1159 | #define Free_Pixmap(display, pixmap) \ | 1165 | #define Free_Pixmap(display, pixmap) \ |
| 1160 | ns_release_object (pixmap) | 1166 | ns_release_object (pixmap) |
| 1161 | 1167 | ||
| 1162 | #else | 1168 | #else |
| 1163 | 1169 | ||
| 1164 | #define Destroy_Image(ximg, dummy) \ | ||
| 1165 | XDestroyImage (ximg) | ||
| 1166 | |||
| 1167 | #define Free_Pixmap(display, pixmap) \ | 1170 | #define Free_Pixmap(display, pixmap) \ |
| 1168 | XFreePixmap (display, pixmap) | 1171 | XFreePixmap (display, pixmap) |
| 1169 | 1172 | ||
| @@ -1187,22 +1190,12 @@ image_background (struct image *img, struct frame *f, XImagePtr_or_DC ximg) | |||
| 1187 | #endif /* HAVE_NTGUI */ | 1190 | #endif /* HAVE_NTGUI */ |
| 1188 | 1191 | ||
| 1189 | if (free_ximg) | 1192 | if (free_ximg) |
| 1190 | { | 1193 | ximg = image_get_x_image_or_dc (f, img, 0, &prev); |
| 1191 | #ifndef HAVE_NTGUI | ||
| 1192 | ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, | ||
| 1193 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 1194 | #else | ||
| 1195 | HDC frame_dc = get_frame_dc (f); | ||
| 1196 | ximg = CreateCompatibleDC (frame_dc); | ||
| 1197 | release_frame_dc (f, frame_dc); | ||
| 1198 | prev = SelectObject (ximg, img->pixmap); | ||
| 1199 | #endif /* !HAVE_NTGUI */ | ||
| 1200 | } | ||
| 1201 | 1194 | ||
| 1202 | img->background = four_corners_best (ximg, img->corners, img->width, img->height); | 1195 | img->background = four_corners_best (ximg, img->corners, img->width, img->height); |
| 1203 | 1196 | ||
| 1204 | if (free_ximg) | 1197 | if (free_ximg) |
| 1205 | Destroy_Image (ximg, prev); | 1198 | image_unget_x_image_or_dc (img, 0, ximg, prev); |
| 1206 | 1199 | ||
| 1207 | img->background_valid = 1; | 1200 | img->background_valid = 1; |
| 1208 | } | 1201 | } |
| @@ -1228,23 +1221,13 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D | |||
| 1228 | #endif /* HAVE_NTGUI */ | 1221 | #endif /* HAVE_NTGUI */ |
| 1229 | 1222 | ||
| 1230 | if (free_mask) | 1223 | if (free_mask) |
| 1231 | { | 1224 | mask = image_get_x_image_or_dc (f, img, 1, &prev); |
| 1232 | #ifndef HAVE_NTGUI | ||
| 1233 | mask = XGetImage (FRAME_X_DISPLAY (f), img->mask, | ||
| 1234 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 1235 | #else | ||
| 1236 | HDC frame_dc = get_frame_dc (f); | ||
| 1237 | mask = CreateCompatibleDC (frame_dc); | ||
| 1238 | release_frame_dc (f, frame_dc); | ||
| 1239 | prev = SelectObject (mask, img->mask); | ||
| 1240 | #endif /* HAVE_NTGUI */ | ||
| 1241 | } | ||
| 1242 | 1225 | ||
| 1243 | img->background_transparent | 1226 | img->background_transparent |
| 1244 | = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN); | 1227 | = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN); |
| 1245 | 1228 | ||
| 1246 | if (free_mask) | 1229 | if (free_mask) |
| 1247 | Destroy_Image (mask, prev); | 1230 | image_unget_x_image_or_dc (img, 1, mask, prev); |
| 1248 | } | 1231 | } |
| 1249 | else | 1232 | else |
| 1250 | img->background_transparent = 0; | 1233 | img->background_transparent = 0; |
| @@ -1260,30 +1243,58 @@ image_background_transparent (struct image *img, struct frame *f, XImagePtr_or_D | |||
| 1260 | Helper functions for X image types | 1243 | Helper functions for X image types |
| 1261 | ***********************************************************************/ | 1244 | ***********************************************************************/ |
| 1262 | 1245 | ||
| 1263 | /* Clear X resources of image IMG on frame F. PIXMAP_P means free the | 1246 | /* Clear X resources of image IMG on frame F according to FLAGS. |
| 1264 | pixmap if any. MASK_P means clear the mask pixmap if any. | 1247 | FLAGS is bitwise-or of the following masks: |
| 1265 | COLORS_P means free colors allocated for the image, if any. */ | 1248 | CLEAR_IMAGE_PIXMAP free the pixmap if any. |
| 1249 | CLEAR_IMAGE_MASK means clear the mask pixmap if any. | ||
| 1250 | CLEAR_IMAGE_COLORS means free colors allocated for the image, if | ||
| 1251 | any. */ | ||
| 1252 | |||
| 1253 | #define CLEAR_IMAGE_PIXMAP (1 << 0) | ||
| 1254 | #define CLEAR_IMAGE_MASK (1 << 1) | ||
| 1255 | #define CLEAR_IMAGE_COLORS (1 << 2) | ||
| 1266 | 1256 | ||
| 1267 | static void | 1257 | static void |
| 1268 | x_clear_image_1 (struct frame *f, struct image *img, bool pixmap_p, | 1258 | x_clear_image_1 (struct frame *f, struct image *img, int flags) |
| 1269 | bool mask_p, bool colors_p) | ||
| 1270 | { | 1259 | { |
| 1271 | if (pixmap_p && img->pixmap) | 1260 | if (flags & CLEAR_IMAGE_PIXMAP) |
| 1272 | { | 1261 | { |
| 1273 | Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap); | 1262 | if (img->pixmap) |
| 1274 | img->pixmap = NO_PIXMAP; | 1263 | { |
| 1275 | /* NOTE (HAVE_NS): background color is NOT an indexed color! */ | 1264 | Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap); |
| 1276 | img->background_valid = 0; | 1265 | img->pixmap = NO_PIXMAP; |
| 1266 | /* NOTE (HAVE_NS): background color is NOT an indexed color! */ | ||
| 1267 | img->background_valid = 0; | ||
| 1268 | } | ||
| 1269 | #ifdef HAVE_X_WINDOWS | ||
| 1270 | if (img->ximg) | ||
| 1271 | { | ||
| 1272 | x_destroy_x_image (img->ximg); | ||
| 1273 | img->ximg = NULL; | ||
| 1274 | img->background_valid = 0; | ||
| 1275 | } | ||
| 1276 | #endif | ||
| 1277 | } | 1277 | } |
| 1278 | 1278 | ||
| 1279 | if (mask_p && img->mask) | 1279 | if (flags & CLEAR_IMAGE_MASK) |
| 1280 | { | 1280 | { |
| 1281 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); | 1281 | if (img->mask) |
| 1282 | img->mask = NO_PIXMAP; | 1282 | { |
| 1283 | img->background_transparent_valid = 0; | 1283 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); |
| 1284 | img->mask = NO_PIXMAP; | ||
| 1285 | img->background_transparent_valid = 0; | ||
| 1286 | } | ||
| 1287 | #ifdef HAVE_X_WINDOWS | ||
| 1288 | if (img->mask_img) | ||
| 1289 | { | ||
| 1290 | x_destroy_x_image (img->mask_img); | ||
| 1291 | img->mask_img = NULL; | ||
| 1292 | img->background_transparent_valid = 0; | ||
| 1293 | } | ||
| 1294 | #endif | ||
| 1284 | } | 1295 | } |
| 1285 | 1296 | ||
| 1286 | if (colors_p && img->ncolors) | 1297 | if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors) |
| 1287 | { | 1298 | { |
| 1288 | /* W32_TODO: color table support. */ | 1299 | /* W32_TODO: color table support. */ |
| 1289 | #ifdef HAVE_X_WINDOWS | 1300 | #ifdef HAVE_X_WINDOWS |
| @@ -1302,7 +1313,8 @@ static void | |||
| 1302 | x_clear_image (struct frame *f, struct image *img) | 1313 | x_clear_image (struct frame *f, struct image *img) |
| 1303 | { | 1314 | { |
| 1304 | block_input (); | 1315 | block_input (); |
| 1305 | x_clear_image_1 (f, img, 1, 1, 1); | 1316 | x_clear_image_1 (f, img, |
| 1317 | CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS); | ||
| 1306 | unblock_input (); | 1318 | unblock_input (); |
| 1307 | } | 1319 | } |
| 1308 | 1320 | ||
| @@ -1633,10 +1645,7 @@ postprocess_image (struct frame *f, struct image *img) | |||
| 1633 | x_build_heuristic_mask (f, img, XCDR (mask)); | 1645 | x_build_heuristic_mask (f, img, XCDR (mask)); |
| 1634 | } | 1646 | } |
| 1635 | else if (NILP (mask) && found_p && img->mask) | 1647 | else if (NILP (mask) && found_p && img->mask) |
| 1636 | { | 1648 | x_clear_image_1 (f, img, CLEAR_IMAGE_MASK); |
| 1637 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); | ||
| 1638 | img->mask = NO_PIXMAP; | ||
| 1639 | } | ||
| 1640 | } | 1649 | } |
| 1641 | 1650 | ||
| 1642 | 1651 | ||
| @@ -2094,6 +2103,130 @@ x_put_x_image (struct frame *f, XImagePtr ximg, Pixmap pixmap, int width, int he | |||
| 2094 | #endif | 2103 | #endif |
| 2095 | } | 2104 | } |
| 2096 | 2105 | ||
| 2106 | /* Thin wrapper for x_create_x_image_and_pixmap, so that it matches | ||
| 2107 | with image_put_x_image. */ | ||
| 2108 | |||
| 2109 | static bool | ||
| 2110 | image_create_x_image_and_pixmap (struct frame *f, struct image *img, | ||
| 2111 | int width, int height, int depth, | ||
| 2112 | XImagePtr *ximg, bool mask_p) | ||
| 2113 | { | ||
| 2114 | eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP); | ||
| 2115 | |||
| 2116 | return x_create_x_image_and_pixmap (f, width, height, depth, ximg, | ||
| 2117 | !mask_p ? &img->pixmap : &img->mask); | ||
| 2118 | } | ||
| 2119 | |||
| 2120 | /* Put X image XIMG into image IMG on frame F, as a mask if and only | ||
| 2121 | if MASK_P. On X, this simply records XIMG on a member of IMG, so | ||
| 2122 | it can be put into the pixmap afterwards via image_sync_to_pixmaps. | ||
| 2123 | On the other platforms, it puts XIMG into the pixmap, then frees | ||
| 2124 | the X image and its buffer. */ | ||
| 2125 | |||
| 2126 | static void | ||
| 2127 | image_put_x_image (struct frame *f, struct image *img, XImagePtr ximg, | ||
| 2128 | bool mask_p) | ||
| 2129 | { | ||
| 2130 | #ifdef HAVE_X_WINDOWS | ||
| 2131 | if (!mask_p) | ||
| 2132 | { | ||
| 2133 | eassert (img->ximg == NULL); | ||
| 2134 | img->ximg = ximg; | ||
| 2135 | } | ||
| 2136 | else | ||
| 2137 | { | ||
| 2138 | eassert (img->mask_img == NULL); | ||
| 2139 | img->mask_img = ximg; | ||
| 2140 | } | ||
| 2141 | #else | ||
| 2142 | x_put_x_image (f, ximg, !mask_p ? img->pixmap : img->mask, | ||
| 2143 | img->width, img->height); | ||
| 2144 | x_destroy_x_image (ximg); | ||
| 2145 | #endif | ||
| 2146 | } | ||
| 2147 | |||
| 2148 | #ifdef HAVE_X_WINDOWS | ||
| 2149 | /* Put the X images recorded in IMG on frame F into pixmaps, then free | ||
| 2150 | the X images and their buffers. */ | ||
| 2151 | |||
| 2152 | static void | ||
| 2153 | image_sync_to_pixmaps (struct frame *f, struct image *img) | ||
| 2154 | { | ||
| 2155 | if (img->ximg) | ||
| 2156 | { | ||
| 2157 | x_put_x_image (f, img->ximg, img->pixmap, img->width, img->height); | ||
| 2158 | x_destroy_x_image (img->ximg); | ||
| 2159 | img->ximg = NULL; | ||
| 2160 | } | ||
| 2161 | if (img->mask_img) | ||
| 2162 | { | ||
| 2163 | x_put_x_image (f, img->mask_img, img->mask, img->width, img->height); | ||
| 2164 | x_destroy_x_image (img->mask_img); | ||
| 2165 | img->mask_img = NULL; | ||
| 2166 | } | ||
| 2167 | } | ||
| 2168 | #endif | ||
| 2169 | |||
| 2170 | #ifdef HAVE_NTGUI | ||
| 2171 | /* Create a memory device context for IMG on frame F. It stores the | ||
| 2172 | currently selected GDI object into *PREV for future restoration by | ||
| 2173 | image_unget_x_image_or_dc. */ | ||
| 2174 | |||
| 2175 | static XImagePtr_or_DC | ||
| 2176 | image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p, | ||
| 2177 | HGDIOBJ *prev) | ||
| 2178 | { | ||
| 2179 | HDC frame_dc = get_frame_dc (f); | ||
| 2180 | XImagePtr_or_DC ximg = CreateCompatibleDC (frame_dc); | ||
| 2181 | |||
| 2182 | release_frame_dc (f, frame_dc); | ||
| 2183 | *prev = SelectObject (ximg, !mask_p ? img->pixmap : img->mask); | ||
| 2184 | } | ||
| 2185 | |||
| 2186 | static void image_unget_x_image_or_dc (struct frame *img, bool mask_p, | ||
| 2187 | XImagePtr_or_DC ximg, HGDIOBJ prev) | ||
| 2188 | { | ||
| 2189 | SelectObject (ximg, prev); | ||
| 2190 | DeleteDC (ximg); | ||
| 2191 | } | ||
| 2192 | #else /* !HAVE_NTGUI */ | ||
| 2193 | /* Get the X image for IMG on frame F. The resulting X image data | ||
| 2194 | should be treated as read-only at least on X. */ | ||
| 2195 | |||
| 2196 | static XImagePtr | ||
| 2197 | image_get_x_image (struct frame *f, struct image *img, bool mask_p) | ||
| 2198 | { | ||
| 2199 | #ifdef HAVE_X_WINDOWS | ||
| 2200 | XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img; | ||
| 2201 | |||
| 2202 | if (ximg_in_img) | ||
| 2203 | return ximg_in_img; | ||
| 2204 | else | ||
| 2205 | return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask, | ||
| 2206 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 2207 | #elif defined (HAVE_NS) | ||
| 2208 | XImagePtr pixmap = !mask_p ? img->pixmap : img->mask; | ||
| 2209 | |||
| 2210 | ns_retain_object (pixmap); | ||
| 2211 | return pixmap; | ||
| 2212 | #endif | ||
| 2213 | } | ||
| 2214 | |||
| 2215 | static void image_unget_x_image (struct image *img, bool mask_p, XImagePtr ximg) | ||
| 2216 | { | ||
| 2217 | #ifdef HAVE_X_WINDOWS | ||
| 2218 | XImagePtr ximg_in_img = !mask_p ? img->ximg : img->mask_img; | ||
| 2219 | |||
| 2220 | if (ximg_in_img) | ||
| 2221 | eassert (ximg == ximg_in_img); | ||
| 2222 | else | ||
| 2223 | XDestroyImage (ximg); | ||
| 2224 | #elif defined (HAVE_NS) | ||
| 2225 | ns_release_object (ximg); | ||
| 2226 | #endif | ||
| 2227 | } | ||
| 2228 | #endif /* !HAVE_NTGUI */ | ||
| 2229 | |||
| 2097 | 2230 | ||
| 2098 | /*********************************************************************** | 2231 | /*********************************************************************** |
| 2099 | File Handling | 2232 | File Handling |
| @@ -3461,9 +3594,9 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3461 | &xpm_image, &xpm_mask, | 3594 | &xpm_image, &xpm_mask, |
| 3462 | &attrs); | 3595 | &attrs); |
| 3463 | #else | 3596 | #else |
| 3464 | rc = XpmReadFileToPixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3597 | rc = XpmReadFileToImage (FRAME_X_DISPLAY (f), SSDATA (file), |
| 3465 | SSDATA (file), &img->pixmap, &img->mask, | 3598 | &img->ximg, &img->mask_img, |
| 3466 | &attrs); | 3599 | &attrs); |
| 3467 | #endif /* HAVE_NTGUI */ | 3600 | #endif /* HAVE_NTGUI */ |
| 3468 | } | 3601 | } |
| 3469 | else | 3602 | else |
| @@ -3484,13 +3617,38 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3484 | &xpm_image, &xpm_mask, | 3617 | &xpm_image, &xpm_mask, |
| 3485 | &attrs); | 3618 | &attrs); |
| 3486 | #else | 3619 | #else |
| 3487 | rc = XpmCreatePixmapFromBuffer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | 3620 | rc = XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f), SSDATA (buffer), |
| 3488 | SSDATA (buffer), | 3621 | &img->ximg, &img->mask_img, |
| 3489 | &img->pixmap, &img->mask, | 3622 | &attrs); |
| 3490 | &attrs); | ||
| 3491 | #endif /* HAVE_NTGUI */ | 3623 | #endif /* HAVE_NTGUI */ |
| 3492 | } | 3624 | } |
| 3493 | 3625 | ||
| 3626 | #ifdef HAVE_X_WINDOWS | ||
| 3627 | if (rc == XpmSuccess) | ||
| 3628 | { | ||
| 3629 | img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 3630 | img->ximg->width, img->ximg->height, | ||
| 3631 | img->ximg->depth); | ||
| 3632 | if (img->pixmap == NO_PIXMAP) | ||
| 3633 | { | ||
| 3634 | x_clear_image (f, img); | ||
| 3635 | rc = XpmNoMemory; | ||
| 3636 | } | ||
| 3637 | else if (img->mask_img) | ||
| 3638 | { | ||
| 3639 | img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), | ||
| 3640 | img->mask_img->width, | ||
| 3641 | img->mask_img->height, | ||
| 3642 | img->mask_img->depth); | ||
| 3643 | if (img->mask == NO_PIXMAP) | ||
| 3644 | { | ||
| 3645 | x_clear_image (f, img); | ||
| 3646 | rc = XpmNoMemory; | ||
| 3647 | } | ||
| 3648 | } | ||
| 3649 | } | ||
| 3650 | #endif | ||
| 3651 | |||
| 3494 | if (rc == XpmSuccess) | 3652 | if (rc == XpmSuccess) |
| 3495 | { | 3653 | { |
| 3496 | #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS) | 3654 | #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS) |
| @@ -3549,6 +3707,15 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3549 | #else | 3707 | #else |
| 3550 | XpmFreeAttributes (&attrs); | 3708 | XpmFreeAttributes (&attrs); |
| 3551 | #endif /* HAVE_NTGUI */ | 3709 | #endif /* HAVE_NTGUI */ |
| 3710 | |||
| 3711 | #ifdef HAVE_X_WINDOWS | ||
| 3712 | /* Maybe fill in the background field while we have ximg handy. */ | ||
| 3713 | IMAGE_BACKGROUND (img, f, img->ximg); | ||
| 3714 | if (img->mask_img) | ||
| 3715 | /* Fill in the background_transparent field while we have the | ||
| 3716 | mask handy. */ | ||
| 3717 | image_background_transparent (img, f, img->mask_img); | ||
| 3718 | #endif | ||
| 3552 | } | 3719 | } |
| 3553 | else | 3720 | else |
| 3554 | { | 3721 | { |
| @@ -3847,11 +4014,10 @@ xpm_load_image (struct frame *f, | |||
| 3847 | goto failure; | 4014 | goto failure; |
| 3848 | } | 4015 | } |
| 3849 | 4016 | ||
| 3850 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | 4017 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0) |
| 3851 | &ximg, &img->pixmap) | ||
| 3852 | #ifndef HAVE_NS | 4018 | #ifndef HAVE_NS |
| 3853 | || !x_create_x_image_and_pixmap (f, width, height, 1, | 4019 | || !image_create_x_image_and_pixmap (f, img, width, height, 1, |
| 3854 | &mask_img, &img->mask) | 4020 | &mask_img, 1) |
| 3855 | #endif | 4021 | #endif |
| 3856 | ) | 4022 | ) |
| 3857 | { | 4023 | { |
| @@ -3986,8 +4152,7 @@ xpm_load_image (struct frame *f, | |||
| 3986 | if (NILP (image_spec_value (img->spec, QCbackground, NULL))) | 4152 | if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
| 3987 | IMAGE_BACKGROUND (img, f, ximg); | 4153 | IMAGE_BACKGROUND (img, f, ximg); |
| 3988 | 4154 | ||
| 3989 | x_put_x_image (f, ximg, img->pixmap, width, height); | 4155 | image_put_x_image (f, img, ximg, 0); |
| 3990 | x_destroy_x_image (ximg); | ||
| 3991 | #ifndef HAVE_NS | 4156 | #ifndef HAVE_NS |
| 3992 | if (have_mask) | 4157 | if (have_mask) |
| 3993 | { | 4158 | { |
| @@ -3995,14 +4160,12 @@ xpm_load_image (struct frame *f, | |||
| 3995 | mask handy. */ | 4160 | mask handy. */ |
| 3996 | image_background_transparent (img, f, mask_img); | 4161 | image_background_transparent (img, f, mask_img); |
| 3997 | 4162 | ||
| 3998 | x_put_x_image (f, mask_img, img->mask, width, height); | 4163 | image_put_x_image (f, img, mask_img, 1); |
| 3999 | x_destroy_x_image (mask_img); | ||
| 4000 | } | 4164 | } |
| 4001 | else | 4165 | else |
| 4002 | { | 4166 | { |
| 4003 | x_destroy_x_image (mask_img); | 4167 | x_destroy_x_image (mask_img); |
| 4004 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); | 4168 | x_clear_image_1 (f, img, CLEAR_IMAGE_MASK); |
| 4005 | img->mask = NO_PIXMAP; | ||
| 4006 | } | 4169 | } |
| 4007 | #endif | 4170 | #endif |
| 4008 | return 1; | 4171 | return 1; |
| @@ -4400,17 +4563,8 @@ x_to_xcolors (struct frame *f, struct image *img, bool rgb_p) | |||
| 4400 | memory_full (SIZE_MAX); | 4563 | memory_full (SIZE_MAX); |
| 4401 | colors = xmalloc (sizeof *colors * img->width * img->height); | 4564 | colors = xmalloc (sizeof *colors * img->width * img->height); |
| 4402 | 4565 | ||
| 4403 | #ifndef HAVE_NTGUI | 4566 | /* Get the X image or create a memory device context for IMG. */ |
| 4404 | /* Get the X image IMG->pixmap. */ | 4567 | ximg = image_get_x_image_or_dc (f, img, 0, &prev); |
| 4405 | ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, | ||
| 4406 | 0, 0, img->width, img->height, ~0, ZPixmap); | ||
| 4407 | #else | ||
| 4408 | /* Load the image into a memory device context. */ | ||
| 4409 | hdc = get_frame_dc (f); | ||
| 4410 | ximg = CreateCompatibleDC (hdc); | ||
| 4411 | release_frame_dc (f, hdc); | ||
| 4412 | prev = SelectObject (ximg, img->pixmap); | ||
| 4413 | #endif /* HAVE_NTGUI */ | ||
| 4414 | 4568 | ||
| 4415 | /* Fill the `pixel' members of the XColor array. I wished there | 4569 | /* Fill the `pixel' members of the XColor array. I wished there |
| 4416 | were an easy and portable way to circumvent XGetPixel. */ | 4570 | were an easy and portable way to circumvent XGetPixel. */ |
| @@ -4440,7 +4594,7 @@ x_to_xcolors (struct frame *f, struct image *img, bool rgb_p) | |||
| 4440 | #endif /* HAVE_X_WINDOWS */ | 4594 | #endif /* HAVE_X_WINDOWS */ |
| 4441 | } | 4595 | } |
| 4442 | 4596 | ||
| 4443 | Destroy_Image (ximg, prev); | 4597 | image_unget_x_image_or_dc (img, 0, ximg, prev); |
| 4444 | 4598 | ||
| 4445 | return colors; | 4599 | return colors; |
| 4446 | } | 4600 | } |
| @@ -4505,8 +4659,9 @@ x_from_xcolors (struct frame *f, struct image *img, XColor *colors) | |||
| 4505 | 4659 | ||
| 4506 | init_color_table (); | 4660 | init_color_table (); |
| 4507 | 4661 | ||
| 4508 | x_create_x_image_and_pixmap (f, img->width, img->height, 0, | 4662 | x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_COLORS); |
| 4509 | &oimg, &pixmap); | 4663 | image_create_x_image_and_pixmap (f, img, img->width, img->height, 0, |
| 4664 | &oimg, 0); | ||
| 4510 | p = colors; | 4665 | p = colors; |
| 4511 | for (y = 0; y < img->height; ++y) | 4666 | for (y = 0; y < img->height; ++y) |
| 4512 | for (x = 0; x < img->width; ++x, ++p) | 4667 | for (x = 0; x < img->width; ++x, ++p) |
| @@ -4517,11 +4672,8 @@ x_from_xcolors (struct frame *f, struct image *img, XColor *colors) | |||
| 4517 | } | 4672 | } |
| 4518 | 4673 | ||
| 4519 | xfree (colors); | 4674 | xfree (colors); |
| 4520 | x_clear_image_1 (f, img, 1, 0, 1); | ||
| 4521 | 4675 | ||
| 4522 | x_put_x_image (f, oimg, pixmap, img->width, img->height); | 4676 | image_put_x_image (f, img, oimg, 0); |
| 4523 | x_destroy_x_image (oimg); | ||
| 4524 | img->pixmap = pixmap; | ||
| 4525 | #ifdef COLOR_TABLE_SUPPORT | 4677 | #ifdef COLOR_TABLE_SUPPORT |
| 4526 | img->colors = colors_in_color_table (&img->ncolors); | 4678 | img->colors = colors_in_color_table (&img->ncolors); |
| 4527 | free_color_table (); | 4679 | free_color_table (); |
| @@ -4706,7 +4858,10 @@ x_disable_image (struct frame *f, struct image *img) | |||
| 4706 | #define MaskForeground(f) WHITE_PIX_DEFAULT (f) | 4858 | #define MaskForeground(f) WHITE_PIX_DEFAULT (f) |
| 4707 | 4859 | ||
| 4708 | Display *dpy = FRAME_X_DISPLAY (f); | 4860 | Display *dpy = FRAME_X_DISPLAY (f); |
| 4709 | GC gc = XCreateGC (dpy, img->pixmap, 0, NULL); | 4861 | GC gc; |
| 4862 | |||
| 4863 | image_sync_to_pixmaps (f, img); | ||
| 4864 | gc = XCreateGC (dpy, img->pixmap, 0, NULL); | ||
| 4710 | XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); | 4865 | XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); |
| 4711 | XDrawLine (dpy, img->pixmap, gc, 0, 0, | 4866 | XDrawLine (dpy, img->pixmap, gc, 0, 0, |
| 4712 | img->width - 1, img->height - 1); | 4867 | img->width - 1, img->height - 1); |
| @@ -4781,37 +4936,25 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4781 | unsigned long bg = 0; | 4936 | unsigned long bg = 0; |
| 4782 | 4937 | ||
| 4783 | if (img->mask) | 4938 | if (img->mask) |
| 4784 | { | 4939 | x_clear_image_1 (f, img, CLEAR_IMAGE_MASK); |
| 4785 | Free_Pixmap (FRAME_X_DISPLAY (f), img->mask); | ||
| 4786 | img->mask = NO_PIXMAP; | ||
| 4787 | img->background_transparent_valid = 0; | ||
| 4788 | } | ||
| 4789 | 4940 | ||
| 4790 | #ifndef HAVE_NTGUI | 4941 | #ifndef HAVE_NTGUI |
| 4791 | #ifndef HAVE_NS | 4942 | #ifndef HAVE_NS |
| 4792 | /* Create an image and pixmap serving as mask. */ | 4943 | /* Create an image and pixmap serving as mask. */ |
| 4793 | rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, | 4944 | rc = image_create_x_image_and_pixmap (f, img, img->width, img->height, 1, |
| 4794 | &mask_img, &img->mask); | 4945 | &mask_img, 1); |
| 4795 | if (!rc) | 4946 | if (!rc) |
| 4796 | return; | 4947 | return; |
| 4797 | #endif /* !HAVE_NS */ | 4948 | #endif /* !HAVE_NS */ |
| 4798 | |||
| 4799 | /* Get the X image of IMG->pixmap. */ | ||
| 4800 | ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, 0, 0, | ||
| 4801 | img->width, img->height, | ||
| 4802 | ~0, ZPixmap); | ||
| 4803 | #else | 4949 | #else |
| 4804 | /* Create the bit array serving as mask. */ | 4950 | /* Create the bit array serving as mask. */ |
| 4805 | row_width = (img->width + 7) / 8; | 4951 | row_width = (img->width + 7) / 8; |
| 4806 | mask_img = xzalloc (row_width * img->height); | 4952 | mask_img = xzalloc (row_width * img->height); |
| 4807 | |||
| 4808 | /* Create a memory device context for IMG->pixmap. */ | ||
| 4809 | frame_dc = get_frame_dc (f); | ||
| 4810 | ximg = CreateCompatibleDC (frame_dc); | ||
| 4811 | release_frame_dc (f, frame_dc); | ||
| 4812 | prev = SelectObject (ximg, img->pixmap); | ||
| 4813 | #endif /* HAVE_NTGUI */ | 4953 | #endif /* HAVE_NTGUI */ |
| 4814 | 4954 | ||
| 4955 | /* Get the X image or create a memory device context for IMG. */ | ||
| 4956 | ximg = image_get_x_image_or_dc (f, img, 0, &prev); | ||
| 4957 | |||
| 4815 | /* Determine the background color of ximg. If HOW is `(R G B)' | 4958 | /* Determine the background color of ximg. If HOW is `(R G B)' |
| 4816 | take that as color. Otherwise, use the image's background color. */ | 4959 | take that as color. Otherwise, use the image's background color. */ |
| 4817 | use_img_background = 1; | 4960 | use_img_background = 1; |
| @@ -4858,9 +5001,8 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4858 | /* Fill in the background_transparent field while we have the mask handy. */ | 5001 | /* Fill in the background_transparent field while we have the mask handy. */ |
| 4859 | image_background_transparent (img, f, mask_img); | 5002 | image_background_transparent (img, f, mask_img); |
| 4860 | 5003 | ||
| 4861 | /* Put mask_img into img->mask. */ | 5004 | /* Put mask_img into the image. */ |
| 4862 | x_put_x_image (f, mask_img, img->mask, img->width, img->height); | 5005 | image_put_x_image (f, img, mask_img, 1); |
| 4863 | x_destroy_x_image (mask_img); | ||
| 4864 | #endif /* !HAVE_NS */ | 5006 | #endif /* !HAVE_NS */ |
| 4865 | #else | 5007 | #else |
| 4866 | for (y = 0; y < img->height; ++y) | 5008 | for (y = 0; y < img->height; ++y) |
| @@ -4882,7 +5024,7 @@ x_build_heuristic_mask (struct frame *f, struct image *img, Lisp_Object how) | |||
| 4882 | xfree (mask_img); | 5024 | xfree (mask_img); |
| 4883 | #endif /* HAVE_NTGUI */ | 5025 | #endif /* HAVE_NTGUI */ |
| 4884 | 5026 | ||
| 4885 | Destroy_Image (ximg, prev); | 5027 | image_unget_x_image_or_dc (img, 0, ximg, prev); |
| 4886 | } | 5028 | } |
| 4887 | 5029 | ||
| 4888 | 5030 | ||
| @@ -5110,8 +5252,7 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5110 | goto error; | 5252 | goto error; |
| 5111 | } | 5253 | } |
| 5112 | 5254 | ||
| 5113 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | 5255 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) |
| 5114 | &ximg, &img->pixmap)) | ||
| 5115 | goto error; | 5256 | goto error; |
| 5116 | 5257 | ||
| 5117 | /* Initialize the color hash table. */ | 5258 | /* Initialize the color hash table. */ |
| @@ -5248,9 +5389,8 @@ pbm_load (struct frame *f, struct image *img) | |||
| 5248 | /* Casting avoids a GCC warning. */ | 5389 | /* Casting avoids a GCC warning. */ |
| 5249 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 5390 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 5250 | 5391 | ||
| 5251 | /* Put the image into a pixmap. */ | 5392 | /* Put ximg into the image. */ |
| 5252 | x_put_x_image (f, ximg, img->pixmap, width, height); | 5393 | image_put_x_image (f, img, ximg, 0); |
| 5253 | x_destroy_x_image (ximg); | ||
| 5254 | 5394 | ||
| 5255 | /* X and W32 versions did it here, MAC version above. ++kfs | 5395 | /* X and W32 versions did it here, MAC version above. ++kfs |
| 5256 | img->width = width; | 5396 | img->width = width; |
| @@ -5688,8 +5828,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5688 | 5828 | ||
| 5689 | /* Create the X image and pixmap now, so that the work below can be | 5829 | /* Create the X image and pixmap now, so that the work below can be |
| 5690 | omitted if the image is too large for X. */ | 5830 | omitted if the image is too large for X. */ |
| 5691 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, | 5831 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) |
| 5692 | &img->pixmap)) | ||
| 5693 | goto error; | 5832 | goto error; |
| 5694 | 5833 | ||
| 5695 | /* If image contains simply transparency data, we prefer to | 5834 | /* If image contains simply transparency data, we prefer to |
| @@ -5801,12 +5940,11 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5801 | contains an alpha channel. */ | 5940 | contains an alpha channel. */ |
| 5802 | if (channels == 4 | 5941 | if (channels == 4 |
| 5803 | && !transparent_p | 5942 | && !transparent_p |
| 5804 | && !x_create_x_image_and_pixmap (f, width, height, 1, | 5943 | && !image_create_x_image_and_pixmap (f, img, width, height, 1, |
| 5805 | &mask_img, &img->mask)) | 5944 | &mask_img, 1)) |
| 5806 | { | 5945 | { |
| 5807 | x_destroy_x_image (ximg); | 5946 | x_destroy_x_image (ximg); |
| 5808 | Free_Pixmap (FRAME_X_DISPLAY (f), img->pixmap); | 5947 | x_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP); |
| 5809 | img->pixmap = NO_PIXMAP; | ||
| 5810 | goto error; | 5948 | goto error; |
| 5811 | } | 5949 | } |
| 5812 | 5950 | ||
| @@ -5880,9 +6018,8 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5880 | Casting avoids a GCC warning. */ | 6018 | Casting avoids a GCC warning. */ |
| 5881 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 6019 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 5882 | 6020 | ||
| 5883 | /* Put the image into the pixmap, then free the X image and its buffer. */ | 6021 | /* Put ximg into the image. */ |
| 5884 | x_put_x_image (f, ximg, img->pixmap, width, height); | 6022 | image_put_x_image (f, img, ximg, 0); |
| 5885 | x_destroy_x_image (ximg); | ||
| 5886 | 6023 | ||
| 5887 | /* Same for the mask. */ | 6024 | /* Same for the mask. */ |
| 5888 | if (mask_img) | 6025 | if (mask_img) |
| @@ -5891,8 +6028,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5891 | mask handy. Casting avoids a GCC warning. */ | 6028 | mask handy. Casting avoids a GCC warning. */ |
| 5892 | image_background_transparent (img, f, (XImagePtr_or_DC)mask_img); | 6029 | image_background_transparent (img, f, (XImagePtr_or_DC)mask_img); |
| 5893 | 6030 | ||
| 5894 | x_put_x_image (f, mask_img, img->mask, img->width, img->height); | 6031 | image_put_x_image (f, img, mask_img, 1); |
| 5895 | x_destroy_x_image (mask_img); | ||
| 5896 | } | 6032 | } |
| 5897 | 6033 | ||
| 5898 | return 1; | 6034 | return 1; |
| @@ -6429,7 +6565,7 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6429 | } | 6565 | } |
| 6430 | 6566 | ||
| 6431 | /* Create X image and pixmap. */ | 6567 | /* Create X image and pixmap. */ |
| 6432 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 6568 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) |
| 6433 | { | 6569 | { |
| 6434 | mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; | 6570 | mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; |
| 6435 | sys_longjmp (mgr->setjmp_buffer, 1); | 6571 | sys_longjmp (mgr->setjmp_buffer, 1); |
| @@ -6496,9 +6632,8 @@ jpeg_load_body (struct frame *f, struct image *img, | |||
| 6496 | /* Casting avoids a GCC warning. */ | 6632 | /* Casting avoids a GCC warning. */ |
| 6497 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 6633 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 6498 | 6634 | ||
| 6499 | /* Put the image into the pixmap. */ | 6635 | /* Put ximg into the image. */ |
| 6500 | x_put_x_image (f, ximg, img->pixmap, width, height); | 6636 | image_put_x_image (f, img, ximg, 0); |
| 6501 | x_destroy_x_image (ximg); | ||
| 6502 | return 1; | 6637 | return 1; |
| 6503 | } | 6638 | } |
| 6504 | 6639 | ||
| @@ -6895,8 +7030,8 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6895 | 7030 | ||
| 6896 | /* Create the X image and pixmap. */ | 7031 | /* Create the X image and pixmap. */ |
| 6897 | if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width | 7032 | if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width |
| 6898 | && x_create_x_image_and_pixmap (f, width, height, 0, | 7033 | && image_create_x_image_and_pixmap (f, img, width, height, 0, |
| 6899 | &ximg, &img->pixmap))) | 7034 | &ximg, 0))) |
| 6900 | { | 7035 | { |
| 6901 | fn_TIFFClose (tiff); | 7036 | fn_TIFFClose (tiff); |
| 6902 | return 0; | 7037 | return 0; |
| @@ -6955,9 +7090,8 @@ tiff_load (struct frame *f, struct image *img) | |||
| 6955 | /* Casting avoids a GCC warning on W32. */ | 7090 | /* Casting avoids a GCC warning on W32. */ |
| 6956 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 7091 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 6957 | 7092 | ||
| 6958 | /* Put the image into the pixmap, then free the X image and its buffer. */ | 7093 | /* Put ximg into the image. */ |
| 6959 | x_put_x_image (f, ximg, img->pixmap, width, height); | 7094 | image_put_x_image (f, img, ximg, 0); |
| 6960 | x_destroy_x_image (ximg); | ||
| 6961 | xfree (buf); | 7095 | xfree (buf); |
| 6962 | 7096 | ||
| 6963 | return 1; | 7097 | return 1; |
| @@ -7285,7 +7419,7 @@ gif_load (struct frame *f, struct image *img) | |||
| 7285 | } | 7419 | } |
| 7286 | 7420 | ||
| 7287 | /* Create the X image and pixmap. */ | 7421 | /* Create the X image and pixmap. */ |
| 7288 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 7422 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) |
| 7289 | { | 7423 | { |
| 7290 | fn_DGifCloseFile (gif); | 7424 | fn_DGifCloseFile (gif); |
| 7291 | return 0; | 7425 | return 0; |
| @@ -7469,9 +7603,8 @@ gif_load (struct frame *f, struct image *img) | |||
| 7469 | /* Casting avoids a GCC warning. */ | 7603 | /* Casting avoids a GCC warning. */ |
| 7470 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 7604 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 7471 | 7605 | ||
| 7472 | /* Put the image into the pixmap, then free the X image and its buffer. */ | 7606 | /* Put ximg into the image. */ |
| 7473 | x_put_x_image (f, ximg, img->pixmap, width, height); | 7607 | image_put_x_image (f, img, ximg, 0); |
| 7474 | x_destroy_x_image (ximg); | ||
| 7475 | 7608 | ||
| 7476 | return 1; | 7609 | return 1; |
| 7477 | } | 7610 | } |
| @@ -7909,8 +8042,8 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7909 | int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ | 8042 | int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ |
| 7910 | const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ | 8043 | const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ |
| 7911 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ | 8044 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ |
| 7912 | if (!x_create_x_image_and_pixmap (f, width, height, imagedepth, | 8045 | if (!image_create_x_image_and_pixmap (f, img, width, height, imagedepth, |
| 7913 | &ximg, &img->pixmap)) | 8046 | &ximg, 0)) |
| 7914 | { | 8047 | { |
| 7915 | #ifdef COLOR_TABLE_SUPPORT | 8048 | #ifdef COLOR_TABLE_SUPPORT |
| 7916 | free_color_table (); | 8049 | free_color_table (); |
| @@ -7948,8 +8081,8 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 7948 | size_t image_height; | 8081 | size_t image_height; |
| 7949 | 8082 | ||
| 7950 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ | 8083 | /* Try to create a x pixmap to hold the imagemagick pixmap. */ |
| 7951 | if (!x_create_x_image_and_pixmap (f, width, height, 0, | 8084 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, |
| 7952 | &ximg, &img->pixmap)) | 8085 | &ximg, 0)) |
| 7953 | { | 8086 | { |
| 7954 | #ifdef COLOR_TABLE_SUPPORT | 8087 | #ifdef COLOR_TABLE_SUPPORT |
| 7955 | free_color_table (); | 8088 | free_color_table (); |
| @@ -8003,10 +8136,8 @@ imagemagick_load_image (struct frame *f, struct image *img, | |||
| 8003 | img->width = width; | 8136 | img->width = width; |
| 8004 | img->height = height; | 8137 | img->height = height; |
| 8005 | 8138 | ||
| 8006 | /* Put the image into the pixmap, then free the X image and its | 8139 | /* Put ximg into the image. */ |
| 8007 | buffer. */ | 8140 | image_put_x_image (f, img, ximg, 0); |
| 8008 | x_put_x_image (f, ximg, img->pixmap, width, height); | ||
| 8009 | x_destroy_x_image (ximg); | ||
| 8010 | 8141 | ||
| 8011 | /* Final cleanup. image_wand should be the only resource left. */ | 8142 | /* Final cleanup. image_wand should be the only resource left. */ |
| 8012 | DestroyMagickWand (image_wand); | 8143 | DestroyMagickWand (image_wand); |
| @@ -8400,7 +8531,7 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * | |||
| 8400 | eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); | 8531 | eassert (fn_gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); |
| 8401 | 8532 | ||
| 8402 | /* Try to create a x pixmap to hold the svg pixmap. */ | 8533 | /* Try to create a x pixmap to hold the svg pixmap. */ |
| 8403 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 8534 | if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) |
| 8404 | { | 8535 | { |
| 8405 | fn_g_object_unref (pixbuf); | 8536 | fn_g_object_unref (pixbuf); |
| 8406 | return 0; | 8537 | return 0; |
| @@ -8475,10 +8606,8 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. * | |||
| 8475 | Casting avoids a GCC warning. */ | 8606 | Casting avoids a GCC warning. */ |
| 8476 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); | 8607 | IMAGE_BACKGROUND (img, f, (XImagePtr_or_DC)ximg); |
| 8477 | 8608 | ||
| 8478 | /* Put the image into the pixmap, then free the X image and its | 8609 | /* Put ximg into the image. */ |
| 8479 | buffer. */ | 8610 | image_put_x_image (f, img, ximg, 0); |
| 8480 | x_put_x_image (f, ximg, img->pixmap, width, height); | ||
| 8481 | x_destroy_x_image (ximg); | ||
| 8482 | 8611 | ||
| 8483 | return 1; | 8612 | return 1; |
| 8484 | 8613 | ||