if (--bm->refcount == 0)
{
- BLOCK_INPUT;
+ block_input ();
free_bitmap_record (dpyinfo, bm);
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
}
width = x_bitmap_width (f, id);
height = x_bitmap_height (f, id);
- BLOCK_INPUT;
+ block_input ();
ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
~0, ZPixmap);
if (!ximg)
{
- UNBLOCK_INPUT;
+ unblock_input ();
return -1;
}
result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
- UNBLOCK_INPUT;
+ unblock_input ();
if (!result)
{
XDestroyImage (ximg);
}
}
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
width, height);
/* Function prototypes. */
-static Lisp_Object define_image_type (struct image_type *type, int loaded);
-static struct image_type *lookup_image_type (Lisp_Object symbol);
+static struct image_type *define_image_type (struct image_type *);
+static struct image_type *lookup_image_type (Lisp_Object);
static void image_error (const char *format, Lisp_Object, Lisp_Object);
static void x_laplace (struct frame *, struct image *);
static void x_emboss (struct frame *, struct image *);
/* Define a new image type from TYPE. This adds a copy of TYPE to
image_types and caches the loading status of TYPE. */
-static Lisp_Object
-define_image_type (struct image_type *type, int loaded)
+static struct image_type *
+define_image_type (struct image_type *type)
{
- Lisp_Object success;
+ struct image_type *p = NULL;
+ Lisp_Object target_type = *type->type;
+ int type_valid = 1;
- if (!loaded)
- success = Qnil;
- else
+ block_input ();
+
+ for (p = image_types; p; p = p->next)
+ if (EQ (*p->type, target_type))
+ goto done;
+
+ if (type->init)
+ {
+#ifdef HAVE_NTGUI
+ /* If we failed to load the library before, don't try again. */
+ Lisp_Object tested = Fassq (target_type, Vlibrary_cache);
+ if (CONSP (tested) && NILP (XCDR (tested)))
+ type_valid = 0;
+ else
+#endif
+ {
+ type_valid = type->init ();
+ CACHE_IMAGE_TYPE (target_type, type_valid ? Qt : Qnil);
+ }
+ }
+
+ if (type_valid)
{
/* Make a copy of TYPE to avoid a bus error in a dumped Emacs.
The initialized data segment is read-only. */
- struct image_type *p = xmalloc (sizeof *p);
+ p = xmalloc (sizeof *p);
*p = *type;
p->next = image_types;
image_types = p;
- success = Qt;
}
- CACHE_IMAGE_TYPE (*type->type, success);
- return success;
-}
-
-
-/* Look up image type SYMBOL, and return a pointer to its image_type
- structure. Value is null if SYMBOL is not a known image type. */
-
-static inline struct image_type *
-lookup_image_type (Lisp_Object symbol)
-{
- struct image_type *type;
-
- /* We must initialize the image-type if it hasn't been already. */
- if (NILP (Finit_image_library (symbol, Vdynamic_library_alist)))
- return 0; /* unimplemented */
-
- for (type = image_types; type; type = type->next)
- if (EQ (symbol, *type->type))
- break;
-
- return type;
+ done:
+ unblock_input ();
+ return p;
}
static void
x_clear_image (struct frame *f, struct image *img)
{
- BLOCK_INPUT;
+ block_input ();
x_clear_image_1 (f, img, 1, 1, 1);
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* Block input so that we won't be interrupted by a SIGIO
while being in an inconsistent state. */
- BLOCK_INPUT;
+ block_input ();
if (!NILP (filter))
{
++windows_or_buffers_changed;
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
}
/* If not found, create a new image and cache it. */
if (img == NULL)
{
- BLOCK_INPUT;
+ block_input ();
img = make_image (spec, hash);
cache_image (f, img);
img->load_failed_p = img->type->load (f, img) == 0;
postprocess_image (f, img);
}
- UNBLOCK_INPUT;
+ unblock_input ();
}
/* We're using IMG, so set its timestamp to `now'. */
Window window = FRAME_X_WINDOW (f);
Screen *screen = FRAME_X_SCREEN (f);
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
if (depth <= 0)
depth = DefaultDepthOfScreen (screen);
static void
x_destroy_x_image (XImagePtr ximg)
{
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
if (ximg)
{
#ifdef HAVE_X_WINDOWS
#ifdef HAVE_X_WINDOWS
GC gc;
- eassert (interrupt_input_blocked);
+ eassert (input_blocked_p ());
gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, ximg, 0, 0, 0, 0, width, height);
XFreeGC (FRAME_X_DISPLAY (f), gc);
xbm_image_p,
xbm_load,
x_clear_image,
+ NULL,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_xpm_functions (void);
+#else
+#define init_xpm_functions NULL
+#endif
+
/* Structure describing the image type XPM. */
static struct image_type xpm_type =
xpm_image_p,
xpm_load,
x_clear_image,
+ init_xpm_functions,
NULL
};
DEF_IMGLIB_FN (void, XImageFree, (xpm_XImage *));
static int
-init_xpm_functions (Lisp_Object libraries)
+init_xpm_functions (void)
{
HMODULE library;
- if (!(library = w32_delayed_load (libraries, Qxpm)))
+ if (!(library = w32_delayed_load (Qxpm)))
return 0;
LOAD_IMGLIB_FN (library, XpmFreeAttributes);
x_query_color (f, &color);
rc = x_alloc_nearest_color (f, cmap, &color);
#else
- BLOCK_INPUT;
+ block_input ();
cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
color.pixel = pixel;
XQueryColor (NULL, cmap, &color);
rc = x_alloc_nearest_color (f, cmap, &color);
- UNBLOCK_INPUT;
+ unblock_input ();
#endif /* HAVE_X_WINDOWS */
if (rc)
pbm_image_p,
pbm_load,
x_clear_image,
+ NULL,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_png_functions (void);
+#else
+#define init_png_functions NULL
+#endif
+
/* Structure describing the image type `png'. */
static struct image_type png_type =
png_image_p,
png_load,
x_clear_image,
+ init_png_functions,
NULL
};
#endif /* libpng version >= 1.5 */
static int
-init_png_functions (Lisp_Object libraries)
+init_png_functions (void)
{
HMODULE library;
- if (!(library = w32_delayed_load (libraries, Qpng)))
+ if (!(library = w32_delayed_load (Qpng)))
return 0;
LOAD_IMGLIB_FN (library, png_get_io_ptr);
#endif /* HAVE_NTGUI */
+/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
+ Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
+ substitute may munge the signal mask, but that should be OK here.
+ MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
+ the system header setjmp.h; don't mess up that. */
+#ifndef HAVE__SETJMP
+# define _setjmp(j) setjmp (j)
+# define _longjmp longjmp
+#endif
#if (PNG_LIBPNG_VER < 10500)
#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
struct png_load_context
{
- /* These are members so that _longjmp doesn't munge local variables. */
+ /* These are members so that longjmp doesn't munge local variables. */
png_struct *png_ptr;
png_info *info_ptr;
png_info *end_info;
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_jpeg_functions (void);
+#else
+#define init_jpeg_functions NULL
+#endif
+
/* Structure describing the image type `jpeg'. */
static struct image_type jpeg_type =
jpeg_image_p,
jpeg_load,
x_clear_image,
+ init_jpeg_functions,
NULL
};
DEF_IMGLIB_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
static int
-init_jpeg_functions (Lisp_Object libraries)
+init_jpeg_functions (void)
{
HMODULE library;
- if (!(library = w32_delayed_load (libraries, Qjpeg)))
+ if (!(library = w32_delayed_load (Qjpeg)))
return 0;
LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
struct my_jpeg_error_mgr
{
struct jpeg_error_mgr pub;
- jmp_buf setjmp_buffer;
+ sys_jmp_buf setjmp_buffer;
- /* The remaining members are so that _longjmp doesn't munge local
+ /* The remaining members are so that longjmp doesn't munge local
variables. */
struct jpeg_decompress_struct cinfo;
enum
MY_JPEG_INVALID_IMAGE_SIZE,
MY_JPEG_CANNOT_CREATE_X
} failure_code;
+#ifdef lint
+ FILE *fp;
+#endif
};
{
struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
mgr->failure_code = MY_JPEG_ERROR_EXIT;
- _longjmp (mgr->setjmp_buffer, 1);
+ sys_longjmp (mgr->setjmp_buffer, 1);
}
return 0;
}
+ IF_LINT (mgr->fp = fp);
+
/* Customize libjpeg's error handling to call my_error_exit when an
error is detected. This function will perform a longjmp. */
mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
mgr->pub.error_exit = my_error_exit;
- if (_setjmp (mgr->setjmp_buffer))
+ if (sys_setjmp (mgr->setjmp_buffer))
{
switch (mgr->failure_code)
{
return 0;
}
+ /* Silence a bogus diagnostic; see GCC bug 54561. */
+ IF_LINT (fp = mgr->fp);
+
/* Create the JPEG decompression object. Let it read from fp.
Read the JPEG image header. */
fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
if (!check_image_size (f, width, height))
{
mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
- _longjmp (mgr->setjmp_buffer, 1);
+ sys_longjmp (mgr->setjmp_buffer, 1);
}
/* Create X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
- _longjmp (mgr->setjmp_buffer, 1);
+ sys_longjmp (mgr->setjmp_buffer, 1);
}
/* Allocate colors. When color quantization is used,
{":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_tiff_functions (void);
+#else
+#define init_tiff_functions NULL
+#endif
+
/* Structure describing the image type `tiff'. */
static struct image_type tiff_type =
tiff_image_p,
tiff_load,
x_clear_image,
+ init_tiff_functions,
NULL
};
DEF_IMGLIB_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
static int
-init_tiff_functions (Lisp_Object libraries)
+init_tiff_functions (void)
{
HMODULE library;
- if (!(library = w32_delayed_load (libraries, Qtiff)))
+ if (!(library = w32_delayed_load (Qtiff)))
return 0;
LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_gif_functions (void);
+#else
+#define init_gif_functions NULL
+#endif
+
/* Structure describing the image type `gif'. */
static struct image_type gif_type =
gif_image_p,
gif_load,
gif_clear_image,
+ init_gif_functions,
NULL
};
DEF_IMGLIB_FN (GifFileType *, DGifOpenFileName, (const char *));
static int
-init_gif_functions (Lisp_Object libraries)
+init_gif_functions (void)
{
HMODULE library;
- if (!(library = w32_delayed_load (libraries, Qgif)))
+ if (!(library = w32_delayed_load (Qgif)))
return 0;
LOAD_IMGLIB_FN (library, DGifCloseFile);
{":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_imagemagick_functions (void);
+#else
+#define init_imagemagick_functions NULL
+#endif
+
/* Structure describing the image type for any image handled via
ImageMagick. */
imagemagick_image_p,
imagemagick_load,
imagemagick_clear_image,
+ init_imagemagick_functions,
NULL
};
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
+#ifdef HAVE_NTGUI
+static int init_svg_functions (void);
+#else
+#define init_svg_functions NULL
+#endif
+
/* Structure describing the image type `svg'. Its the same type of
structure defined for all image formats, handled by emacs image
functions. See struct image_type in dispextern.h. */
static struct image_type svg_type =
{
- /* An identifier showing that this is an image structure for the SVG format. */
&Qsvg,
- /* Handle to a function that can be used to identify a SVG file. */
svg_image_p,
- /* Handle to function used to load a SVG file. */
svg_load,
- /* Handle to function to free sresources for SVG. */
x_clear_image,
- /* An internal field to link to the next image type in a list of
- image types, will be filled in when registering the format. */
+ init_svg_functions,
NULL
};
Lisp_Object Qgdk_pixbuf, Qglib, Qgobject;
static int
-init_svg_functions (Lisp_Object libraries)
+init_svg_functions (void)
{
HMODULE library, gdklib, glib, gobject;
- if (!(glib = w32_delayed_load (libraries, Qglib))
- || !(gobject = w32_delayed_load (libraries, Qgobject))
- || !(gdklib = w32_delayed_load (libraries, Qgdk_pixbuf))
- || !(library = w32_delayed_load (libraries, Qsvg)))
+ if (!(glib = w32_delayed_load (Qglib))
+ || !(gobject = w32_delayed_load (Qgobject))
+ || !(gdklib = w32_delayed_load (Qgdk_pixbuf))
+ || !(library = w32_delayed_load (Qsvg)))
return 0;
LOAD_IMGLIB_FN (library, rsvg_handle_new);
gs_image_p,
gs_load,
gs_clear_image,
+ NULL,
NULL
};
if (x_check_image_size (0, img->width, img->height))
{
/* Only W32 version did BLOCK_INPUT here. ++kfs */
- BLOCK_INPUT;
+ block_input ();
img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
img->width, img->height,
DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
- UNBLOCK_INPUT;
+ unblock_input ();
}
if (!img->pixmap)
{
XImagePtr ximg;
- BLOCK_INPUT;
+ block_input ();
/* Try to get an XImage for img->pixmep. */
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
image_error ("Cannot get X image of `%s'; colors will not be freed",
img->spec, Qnil);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_X_WINDOWS */
/* Now that we have the pixmap, compute mask and transform the
image if requested. */
- BLOCK_INPUT;
+ block_input ();
postprocess_image (f, img);
- UNBLOCK_INPUT;
+ unblock_input ();
}
#endif /* HAVE_GHOSTSCRIPT */
Initialization
***********************************************************************/
-#ifdef HAVE_NTGUI
-/* Image types that rely on external libraries are loaded dynamically
- if the library is available. */
-#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
- define_image_type (image_type, init_lib_fn (libraries))
-#else
-#define CHECK_LIB_AVAILABLE(image_type, init_lib_fn, libraries) \
- define_image_type (image_type, 1)
-#endif /* HAVE_NTGUI */
-
-DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 2, 2, 0,
+DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
doc: /* Initialize image library implementing image type TYPE.
Return non-nil if TYPE is a supported image type.
-Image types pbm and xbm are prebuilt; other types are loaded here.
-Libraries to load are specified in alist LIBRARIES (usually, the value
-of `dynamic-library-alist', which see). */)
- (Lisp_Object type, Lisp_Object libraries)
+If image libraries are loaded dynamically (currently only the case on
+MS-Windows), load the library for TYPE if it is not yet loaded, using
+the library file(s) specified by `dynamic-library-alist'. */)
+ (Lisp_Object type)
{
-#ifdef HAVE_NTGUI
- /* Don't try to reload the library. */
- Lisp_Object tested = Fassq (type, Vlibrary_cache);
- if (CONSP (tested))
- return XCDR (tested);
-#endif
+ return lookup_image_type (type) ? Qt : Qnil;
+}
+/* Look up image type TYPE, and return a pointer to its image_type
+ structure. Return 0 if TYPE is not a known image type. */
+
+static struct image_type *
+lookup_image_type (Lisp_Object type)
+{
/* Types pbm and xbm are built-in and always available. */
- if (EQ (type, Qpbm) || EQ (type, Qxbm))
- return Qt;
+ if (EQ (type, Qpbm))
+ return define_image_type (&pbm_type);
+
+ if (EQ (type, Qxbm))
+ return define_image_type (&xbm_type);
#if defined (HAVE_XPM) || defined (HAVE_NS)
if (EQ (type, Qxpm))
- return CHECK_LIB_AVAILABLE (&xpm_type, init_xpm_functions, libraries);
+ return define_image_type (&xpm_type);
#endif
#if defined (HAVE_JPEG) || defined (HAVE_NS)
if (EQ (type, Qjpeg))
- return CHECK_LIB_AVAILABLE (&jpeg_type, init_jpeg_functions, libraries);
+ return define_image_type (&jpeg_type);
#endif
#if defined (HAVE_TIFF) || defined (HAVE_NS)
if (EQ (type, Qtiff))
- return CHECK_LIB_AVAILABLE (&tiff_type, init_tiff_functions, libraries);
+ return define_image_type (&tiff_type);
#endif
#if defined (HAVE_GIF) || defined (HAVE_NS)
if (EQ (type, Qgif))
- return CHECK_LIB_AVAILABLE (&gif_type, init_gif_functions, libraries);
+ return define_image_type (&gif_type);
#endif
#if defined (HAVE_PNG) || defined (HAVE_NS)
if (EQ (type, Qpng))
- return CHECK_LIB_AVAILABLE (&png_type, init_png_functions, libraries);
+ return define_image_type (&png_type);
#endif
#if defined (HAVE_RSVG)
if (EQ (type, Qsvg))
- return CHECK_LIB_AVAILABLE (&svg_type, init_svg_functions, libraries);
+ return define_image_type (&svg_type);
#endif
#if defined (HAVE_IMAGEMAGICK)
if (EQ (type, Qimagemagick))
- return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
- libraries);
+ return define_image_type (&imagemagick_type);
#endif
#ifdef HAVE_GHOSTSCRIPT
if (EQ (type, Qpostscript))
- return CHECK_LIB_AVAILABLE (&gs_type, init_gs_functions, libraries);
+ return define_image_type (&gs_type);
#endif
- /* If the type is not recognized, avoid testing it ever again. */
- CACHE_IMAGE_TYPE (type, Qnil);
- return Qnil;
+ return NULL;
}
void
non-numeric, there is no explicit limit on the size of images. */);
Vmax_image_size = make_float (MAX_IMAGE_SIZE);
- DEFSYM (Qpbm, "pbm");
- ADD_IMAGE_TYPE (Qpbm);
-
- DEFSYM (Qxbm, "xbm");
- ADD_IMAGE_TYPE (Qxbm);
-
- define_image_type (&xbm_type, 1);
- define_image_type (&pbm_type, 1);
-
DEFSYM (Qcount, "count");
DEFSYM (Qextension_data, "extension-data");
DEFSYM (Qdelay, "delay");
);
#endif
+ DEFSYM (Qpbm, "pbm");
+ ADD_IMAGE_TYPE (Qpbm);
+
+ DEFSYM (Qxbm, "xbm");
+ ADD_IMAGE_TYPE (Qxbm);
+
#if defined (HAVE_XPM) || defined (HAVE_NS)
DEFSYM (Qxpm, "xpm");
ADD_IMAGE_TYPE (Qxpm);