#include <dlgs.h>
#define FILE_NAME_TEXT_FIELD edt1
+void syms_of_w32fns ();
+void globals_of_w32fns ();
+static void init_external_image_libraries ();
+
extern void free_frame_menubar ();
extern void x_compute_fringe_widths P_ ((struct frame *, int));
extern double atof ();
over text or in the modeline. */
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape;
-Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape;
+Lisp_Object Vx_hourglass_pointer_shape, Vx_window_horizontal_drag_shape, Vx_hand_shape;
/* The shape when over mouse-sensitive text. */
Lisp_Object Vx_sensitive_text_pointer_shape;
+#ifndef IDC_HAND
+#define IDC_HAND MAKEINTRESOURCE(32649)
+#endif
+
/* Color of chars displayed in cursor box. */
Lisp_Object Vx_cursor_fore_pixel;
else
horizontal_drag_cursor
= XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
+ /* TODO: hand_cursor */
/* Check and report errors with the above calls. */
x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
&fore_color, &back_color);
XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
&fore_color, &back_color);
+ /* TODO: hand_cursor */
}
if (FRAME_W32_WINDOW (f) != 0)
&& f->output_data.w32->cross_cursor != 0)
XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->cross_cursor);
f->output_data.w32->cross_cursor = cross_cursor;
+ /* TODO: hand_cursor */
XFlush (FRAME_W32_DISPLAY (f));
UNBLOCK_INPUT;
{
set_frame_cursor_types (f, arg);
- /* Make sure the cursor gets redrawn. This is overkill, but how
- often do people change cursor types? */
- update_mode_lines++;
+ /* Make sure the cursor gets redrawn. */
+ cursor_type_changed = 1;
}
\f
void
strcat (name_key, ".");
strcat (name_key, SDATA (attribute));
- value = x_get_string_resource (Qnil,
+ value = x_get_string_resource (check_x_display_info (Qnil)->xrdb,
name_key, class_key);
if (value != (char *) 0)
attribute);
sprintf (class_key, "%s.%s", EMACS_CLASS, class);
- return x_get_string_resource (sf, name_key, class_key);
+ return x_get_string_resource (FRAME_X_DISPLAY_INFO (sf)->xrdb,
+ name_key, class_key);
}
/* Types we might convert a resource string into. */
}
\f
+Cursor
+w32_load_cursor (LPCTSTR name)
+{
+ /* Try first to load cursor from application resource. */
+ Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle(NULL),
+ name, IMAGE_CURSOR, 0, 0,
+ LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
+ if (!cursor)
+ {
+ /* Then try to load a shared predefined cursor. */
+ cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0,
+ LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED);
+ }
+ return cursor;
+}
extern LRESULT CALLBACK w32_wnd_proc ();
wc.cbWndExtra = WND_EXTRA_BYTES;
wc.hInstance = hinst;
wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
- wc.hCursor = LoadCursor (NULL, IDC_ARROW);
+ wc.hCursor = w32_load_cursor (IDC_ARROW);
wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */
wc.lpszMenuName = NULL;
wc.lpszClassName = EMACS_CLASS;
goto dflt;
case WM_SETFOCUS:
- /*
- Reinitialize the function pointer track_mouse_event_fn here.
- This is required even though it is initialized in syms_of_w32fns
- which is called in main (emacs.c).
- Reinitialize the function pointer track_mouse_event_fn here.
- Even though this function pointer is initialized in
- syms_of_w32fns which is called from main (emacs.c),
- we need to initialize it again here in order to prevent
- a crash that occurs in Windows 9x (possibly only when Emacs
- was built on Windows NT / 2000 / XP?) when handling the
- WM_MOUSEMOVE message.
- The crash occurs when attempting to call the Win32 API
- function TrackMouseEvent through the function pointer.
- It appears as if the function pointer that is obtained when
- syms_of_w32fns is called from main is no longer valid
- (possibly due to DLL relocation?).
- To resolve this issue, I have placed a call to reinitialize
- this function pointer here because this message gets received
- when the Emacs window gains focus.
- */
- track_mouse_event_fn =
- (TrackMouseEvent_Proc) GetProcAddress (
- GetModuleHandle ("user32.dll"),
- "TrackMouseEvent");
dpyinfo->faked_key = 0;
reset_modifiers ();
register_hot_keys (hwnd);
((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767;
return 0;
+ case WM_SETCURSOR:
+ if (LOWORD (lParam) == HTCLIENT)
+ return 0;
+
+ goto dflt;
+
+ case WM_EMACS_SETCURSOR:
+ {
+ Cursor cursor = (Cursor) wParam;
+ if (cursor)
+ SetCursor (cursor);
+ return 0;
+ }
+
case WM_EMACS_CREATESCROLLBAR:
return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
(struct scroll_bar *) lParam);
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
+ f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
+ f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
+ f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW);
+ f->output_data.w32->cross_cursor = w32_load_cursor (IDC_CROSS);
+ f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT);
+ f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE);
+ f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND);
+
/* Add the tool-bar height to the initial frame height so that the
user gets a text display area of the size he specified with -g or
via .Xdefaults. Later changes of the tool-bar height don't
{
newlist = Fcons (XCAR (tem), newlist);
n_fonts++;
- if (n_fonts >= max_names)
+ if (max_names >= 0 && n_fonts >= max_names)
break;
}
}
to be listed. Frame F NULL means we have not yet created any
frame, which means we can't get proper size info, as we don't have
a device context to use for GetTextMetrics.
- MAXNAMES sets a limit on how many fonts to match. */
+ MAXNAMES sets a limit on how many fonts to match. If MAXNAMES is
+ negative, then all matching fonts are returned. */
Lisp_Object
w32_list_fonts (f, pattern, size, maxnames)
{
newlist = Fcons (XCAR (tem), newlist);
n_fonts++;
- if (n_fonts >= maxnames)
+ if (maxnames >= 0 && n_fonts >= maxnames)
break;
else
continue;
{
newlist = Fcons (XCAR (tem), newlist);
n_fonts++;
- if (n_fonts >= maxnames)
+ if (maxnames >= 0 && n_fonts >= maxnames)
break;
}
/* keep track of the closest matching size in case
}
/* Include any bdf fonts. */
- if (n_fonts < maxnames)
+ if (n_fonts < maxnames || maxnames < 0)
{
Lisp_Object combined[2];
combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts);
mask = CreateCompatibleDC (frame_dc);
release_frame_dc (f, frame_dc);
- prev = SelectObject (mask, img->mask);
+ prev = SelectObject (mask, img->mask);
}
img->background_transparent
W32 support code
***********************************************************************/
+/* Macro for defining functions that will be loaded from image DLLs. */
+#define DEF_IMGLIB_FN(func) FARPROC fn_##func
+
+/* Macro for loading those image functions from the library. */
+#define LOAD_IMGLIB_FN(lib,func) { \
+ fn_##func = (void *) GetProcAddress (lib, #func); \
+ if (!fn_##func) return 0; \
+ }
+
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
XImage **, Pixmap *));
static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int));
struct frame *f;
XImage *ximg;
Pixmap pixmap;
+ int width, height;
{
#if 0 /* I don't think this is necessary looking at where it is used. */
HDC hdc = get_frame_dc (f);
w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
- bits = (char *) xmalloc (height * w2);
+ bits = (char *) alloca (height * w2);
bzero (bits, height * w2);
for (i = 0; i < height; i++)
{
*p++ = reflect_byte(*data++);
}
bmp = CreateBitmap (width, height, 1, 1, bits);
- xfree (bits);
return bmp;
}
0, 0, SRCCOPY);
SelectObject (old_img_dc, old_prev);
- SelectObject (new_img_dc, new_prev);
+ SelectObject (new_img_dc, new_prev);
DeleteDC (old_img_dc);
DeleteDC (new_img_dc);
DeleteObject (img->pixmap);
static int xpm_load P_ ((struct frame *f, struct image *img));
static int xpm_valid_color_symbols_p P_ ((Lisp_Object));
+/* Indicate to xpm.h that we don't have Xlib. */
+#define FOR_MSW
+/* simx.h in xpm defines XColor and XImage differently than Emacs. */
+#define XColor xpm_XColor
+#define XImage xpm_XImage
+#define PIXEL_ALREADY_TYPEDEFED
#include "X11/xpm.h"
+#undef FOR_MSW
+#undef XColor
+#undef XImage
+#undef PIXEL_ALREADY_TYPEDEFED
/* The symbol `xpm' identifying XPM-format images. */
};
+/* XPM library details. */
+
+DEF_IMGLIB_FN (XpmFreeAttributes);
+DEF_IMGLIB_FN (XpmCreateImageFromBuffer);
+DEF_IMGLIB_FN (XpmReadFileToImage);
+DEF_IMGLIB_FN (XImageFree);
+
+
+static int
+init_xpm_functions (library)
+ HMODULE library;
+{
+ LOAD_IMGLIB_FN (library, XpmFreeAttributes);
+ LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
+ LOAD_IMGLIB_FN (library, XpmReadFileToImage);
+ LOAD_IMGLIB_FN (library, XImageFree);
+
+ return 1;
+}
+
/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list
for XPM images. Such a list must consist of conses whose car and
cdr are strings. */
struct frame *f;
struct image *img;
{
- int rc, i;
+ HDC hdc;
+ int rc;
XpmAttributes attrs;
Lisp_Object specified_file, color_symbols;
+ xpm_XImage * xpm_image, * xpm_mask;
/* Configure the XPM lib. Use the visual of frame F. Allocate
close colors. Return colors allocated. */
bzero (&attrs, sizeof attrs);
+ xpm_image = xpm_mask = NULL;
+
+#if 0
attrs.visual = FRAME_X_VISUAL (f);
attrs.colormap = FRAME_X_COLORMAP (f);
attrs.valuemask |= XpmVisual;
attrs.valuemask |= XpmColormap;
+#endif
attrs.valuemask |= XpmReturnAllocPixels;
#ifdef XpmAllocCloseColors
attrs.alloc_close_colors = 1;
/* Create a pixmap for the image, either from a file, or from a
string buffer containing data in the same format as an XPM file. */
- BLOCK_INPUT;
+
specified_file = image_spec_value (img->spec, QCfile, NULL);
+
+ {
+ HDC frame_dc = get_frame_dc (f);
+ hdc = CreateCompatibleDC (frame_dc);
+ release_frame_dc (f, frame_dc);
+ }
+
if (STRINGP (specified_file))
{
Lisp_Object file = x_find_image_file (specified_file);
if (!STRINGP (file))
{
image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNBLOCK_INPUT;
return 0;
}
- rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f),
- SDATA (file), &img->pixmap, &img->mask,
- &attrs);
+ /* XpmReadFileToPixmap is not available in the Windows port of
+ libxpm. But XpmReadFileToImage almost does what we want. */
+ rc = fn_XpmReadFileToImage (&hdc, SDATA (file),
+ &xpm_image, &xpm_mask,
+ &attrs);
}
else
{
Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
- rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f),
- SDATA (buffer),
- &img->pixmap, &img->mask,
- &attrs);
+ /* XpmCreatePixmapFromBuffer is not available in the Windows port
+ of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
+ rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer),
+ &xpm_image, &xpm_mask,
+ &attrs);
}
- UNBLOCK_INPUT;
if (rc == XpmSuccess)
{
+ int i;
+
+ /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
+ plus some duplicate attributes. */
+ if (xpm_image && xpm_image->bitmap)
+ {
+ img->pixmap = xpm_image->bitmap;
+ /* XImageFree in libXpm frees XImage struct without destroying
+ the bitmap, which is what we want. */
+ fn_XImageFree (xpm_image);
+ }
+ if (xpm_mask && xpm_mask->bitmap)
+ {
+ /* The mask appears to be inverted compared with what we expect.
+ TODO: invert our expectations. See other places where we
+ have to invert bits because our idea of masks is backwards. */
+ HGDIOBJ old_obj;
+ old_obj = SelectObject (hdc, xpm_mask->bitmap);
+
+ PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
+ SelectObject (hdc, old_obj);
+
+ img->mask = xpm_mask->bitmap;
+ fn_XImageFree (xpm_mask);
+ DeleteDC (hdc);
+ }
+
+ DeleteDC (hdc);
+
/* Remember allocated colors. */
img->ncolors = attrs.nalloc_pixels;
img->colors = (unsigned long *) xmalloc (img->ncolors
xassert (img->width > 0 && img->height > 0);
/* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
- BLOCK_INPUT;
- XpmFreeAttributes (&attrs);
- UNBLOCK_INPUT;
+ fn_XpmFreeAttributes (&attrs);
}
else
{
+ DeleteDC (hdc);
+
switch (rc)
{
case XpmOpenFailed:
{
int width = ximg->info.bmiHeader.biWidth;
int height = ximg->info.bmiHeader.biHeight;
- int rowbytes = width * 3;
unsigned char * pixel;
- /* Don't support putting pixels in images with palettes. */
- xassert (ximg->info.bmiHeader.biBitCount == 24);
-
- /* Ensure scanlines are aligned on 4 byte boundaries. */
- if (rowbytes % 4)
- rowbytes += 4 - (rowbytes % 4);
-
- pixel = ximg->data + y * rowbytes + x * 3;
- /* Windows bitmaps are in BGR order. */
- *pixel = GetBValue (color);
- *(pixel + 1) = GetGValue (color);
- *(pixel + 2) = GetRValue (color);
+ /* True color images. */
+ if (ximg->info.bmiHeader.biBitCount == 24)
+ {
+ int rowbytes = width * 3;
+ /* Ensure scanlines are aligned on 4 byte boundaries. */
+ if (rowbytes % 4)
+ rowbytes += 4 - (rowbytes % 4);
+
+ pixel = ximg->data + y * rowbytes + x * 3;
+ /* Windows bitmaps are in BGR order. */
+ *pixel = GetBValue (color);
+ *(pixel + 1) = GetGValue (color);
+ *(pixel + 2) = GetRValue (color);
+ }
+ /* Monochrome images. */
+ else if (ximg->info.bmiHeader.biBitCount == 1)
+ {
+ int rowbytes = width / 8;
+ /* Ensure scanlines are aligned on 4 byte boundaries. */
+ if (rowbytes % 4)
+ rowbytes += 4 - (rowbytes % 4);
+ pixel = ximg->data + y * rowbytes + x / 8;
+ /* Filter out palette info. */
+ if (color & 0x00ffffff)
+ *pixel = *pixel | (1 << x % 8);
+ else
+ *pixel = *pixel & ~(1 << x % 8);
+ }
+ else
+ image_error ("XPutPixel: palette image not supported.", Qnil, Qnil);
}
-
/* Create IMG->pixmap from an array COLORS of XColor structures, whose
RGB members are set. F is the frame on which this all happens.
COLORS will be freed; an existing IMG->pixmap will be freed, too. */
image_background_transparent (img, f, img_dc);
/* Put mask_img into img->mask. */
- x_destroy_x_image (mask_img);
+ x_destroy_x_image ((XImage *)mask_img);
SelectObject (img_dc, prev);
DeleteDC (img_dc);
NULL
};
+/* PNG library details. */
+
+DEF_IMGLIB_FN (png_get_io_ptr);
+DEF_IMGLIB_FN (png_check_sig);
+DEF_IMGLIB_FN (png_create_read_struct);
+DEF_IMGLIB_FN (png_create_info_struct);
+DEF_IMGLIB_FN (png_destroy_read_struct);
+DEF_IMGLIB_FN (png_set_read_fn);
+DEF_IMGLIB_FN (png_init_io);
+DEF_IMGLIB_FN (png_set_sig_bytes);
+DEF_IMGLIB_FN (png_read_info);
+DEF_IMGLIB_FN (png_get_IHDR);
+DEF_IMGLIB_FN (png_get_valid);
+DEF_IMGLIB_FN (png_set_strip_16);
+DEF_IMGLIB_FN (png_set_expand);
+DEF_IMGLIB_FN (png_set_gray_to_rgb);
+DEF_IMGLIB_FN (png_set_background);
+DEF_IMGLIB_FN (png_get_bKGD);
+DEF_IMGLIB_FN (png_read_update_info);
+DEF_IMGLIB_FN (png_get_channels);
+DEF_IMGLIB_FN (png_get_rowbytes);
+DEF_IMGLIB_FN (png_read_image);
+DEF_IMGLIB_FN (png_read_end);
+DEF_IMGLIB_FN (png_error);
+
+static int
+init_png_functions (library)
+ HMODULE library;
+{
+ LOAD_IMGLIB_FN (library, png_get_io_ptr);
+ LOAD_IMGLIB_FN (library, png_check_sig);
+ LOAD_IMGLIB_FN (library, png_create_read_struct);
+ LOAD_IMGLIB_FN (library, png_create_info_struct);
+ LOAD_IMGLIB_FN (library, png_destroy_read_struct);
+ LOAD_IMGLIB_FN (library, png_set_read_fn);
+ LOAD_IMGLIB_FN (library, png_init_io);
+ LOAD_IMGLIB_FN (library, png_set_sig_bytes);
+ LOAD_IMGLIB_FN (library, png_read_info);
+ LOAD_IMGLIB_FN (library, png_get_IHDR);
+ LOAD_IMGLIB_FN (library, png_get_valid);
+ LOAD_IMGLIB_FN (library, png_set_strip_16);
+ LOAD_IMGLIB_FN (library, png_set_expand);
+ LOAD_IMGLIB_FN (library, png_set_gray_to_rgb);
+ LOAD_IMGLIB_FN (library, png_set_background);
+ LOAD_IMGLIB_FN (library, png_get_bKGD);
+ LOAD_IMGLIB_FN (library, png_read_update_info);
+ LOAD_IMGLIB_FN (library, png_get_channels);
+ LOAD_IMGLIB_FN (library, png_get_rowbytes);
+ LOAD_IMGLIB_FN (library, png_read_image);
+ LOAD_IMGLIB_FN (library, png_read_end);
+ LOAD_IMGLIB_FN (library, png_error);
+ return 1;
+}
/* Return non-zero if OBJECT is a valid PNG image specification. */
png_size_t length;
{
struct png_memory_storage *tbr
- = (struct png_memory_storage *) png_get_io_ptr (png_ptr);
+ = (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr);
if (length > tbr->len - tbr->index)
- png_error (png_ptr, "Read error");
+ fn_png_error (png_ptr, "Read error");
bcopy (tbr->bytes + tbr->index, data, length);
tbr->index = tbr->index + length;
png_info *info_ptr = NULL, *end_info = NULL;
FILE *volatile fp = NULL;
png_byte sig[8];
- png_byte *volatile pixels = NULL;
- png_byte **volatile rows = NULL;
+ png_byte * volatile pixels = NULL;
+ png_byte ** volatile rows = NULL;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_byte channels;
png_uint_32 row_bytes;
int transparent_p;
- char *gamma_str;
double screen_gamma, image_gamma;
int intent;
struct png_memory_storage tbr; /* Data to be read */
{
file = x_find_image_file (specified_file);
if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
- return 0;
- }
+ {
+ image_error ("Cannot find image file `%s'", specified_file, Qnil);
+ UNGCPRO;
+ return 0;
+ }
/* Open the image file. */
fp = fopen (SDATA (file), "rb");
if (!fp)
- {
- image_error ("Cannot open image file `%s'", file, Qnil);
- UNGCPRO;
- fclose (fp);
- return 0;
- }
+ {
+ image_error ("Cannot open image file `%s'", file, Qnil);
+ UNGCPRO;
+ fclose (fp);
+ return 0;
+ }
/* Check PNG signature. */
if (fread (sig, 1, sizeof sig, fp) != sizeof sig
- || !png_check_sig (sig, sizeof sig))
- {
- image_error ("Not a PNG file:` %s'", file, Qnil);
- UNGCPRO;
- fclose (fp);
- return 0;
- }
+ || !fn_png_check_sig (sig, sizeof sig))
+ {
+ image_error ("Not a PNG file: `%s'", file, Qnil);
+ UNGCPRO;
+ fclose (fp);
+ return 0;
+ }
}
else
{
/* Check PNG signature. */
if (tbr.len < sizeof sig
- || !png_check_sig (tbr.bytes, sizeof sig))
+ || !fn_png_check_sig (tbr.bytes, sizeof sig))
{
image_error ("Not a PNG image: `%s'", img->spec, Qnil);
UNGCPRO;
}
/* Initialize read and info structs for PNG lib. */
- png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,
- my_png_error, my_png_warning);
+ png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,
+ my_png_error, my_png_warning);
if (!png_ptr)
{
if (fp) fclose (fp);
return 0;
}
- info_ptr = png_create_info_struct (png_ptr);
+ info_ptr = fn_png_create_info_struct (png_ptr);
if (!info_ptr)
{
- png_destroy_read_struct (&png_ptr, NULL, NULL);
+ fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
if (fp) fclose (fp);
UNGCPRO;
return 0;
}
- end_info = png_create_info_struct (png_ptr);
+ end_info = fn_png_create_info_struct (png_ptr);
if (!end_info)
{
- png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
+ fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
if (fp) fclose (fp);
UNGCPRO;
return 0;
{
error:
if (png_ptr)
- png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
+ fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
xfree (pixels);
xfree (rows);
if (fp) fclose (fp);
/* Read image info. */
if (!NILP (specified_data))
- png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
+ fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
else
- png_init_io (png_ptr, fp);
+ fn_png_init_io (png_ptr, fp);
- png_set_sig_bytes (png_ptr, sizeof sig);
- png_read_info (png_ptr, info_ptr);
- png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
- &interlace_type, NULL, NULL);
+ fn_png_set_sig_bytes (png_ptr, sizeof sig);
+ fn_png_read_info (png_ptr, info_ptr);
+ fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ &interlace_type, NULL, NULL);
/* If image contains simply transparency data, we prefer to
construct a clipping mask. */
- if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
+ if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
transparent_p = 1;
else
transparent_p = 0;
/* Strip more than 8 bits per channel. */
if (bit_depth == 16)
- png_set_strip_16 (png_ptr);
+ fn_png_set_strip_16 (png_ptr);
/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
if available. */
- png_set_expand (png_ptr);
+ fn_png_set_expand (png_ptr);
/* Convert grayscale images to RGB. */
if (color_type == PNG_COLOR_TYPE_GRAY
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb (png_ptr);
+ fn_png_set_gray_to_rgb (png_ptr);
- /* The value 2.2 is a guess for PC monitors from PNG example.c. */
- gamma_str = getenv ("SCREEN_GAMMA");
- screen_gamma = gamma_str ? atof (gamma_str) : 2.2;
+ screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2);
+#if 0 /* Avoid double gamma correction for PNG images. */
/* Tell the PNG lib to handle gamma correction for us. */
-
#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
if (png_get_sRGB (png_ptr, info_ptr, &intent))
- /* There is a special chunk in the image specifying the gamma. */
- png_set_sRGB (png_ptr, info_ptr, intent);
+ /* The libpng documentation says this is right in this case. */
+ png_set_gamma (png_ptr, screen_gamma, 0.45455);
else
#endif
if (png_get_gAMA (png_ptr, info_ptr, &image_gamma))
/* Image contains gamma information. */
png_set_gamma (png_ptr, screen_gamma, image_gamma);
else
- /* Use a default of 0.5 for the image gamma. */
- png_set_gamma (png_ptr, screen_gamma, 0.5);
+ /* Use the standard default for the image gamma. */
+ png_set_gamma (png_ptr, screen_gamma, 0.45455);
+#endif /* if 0 */
/* Handle alpha channel by combining the image with a background
color. Do this only if a real alpha channel is supplied. For
simple transparency, we prefer a clipping mask. */
if (!transparent_p)
{
- png_color_16 *image_background;
+ png_color_16 *image_bg;
Lisp_Object specified_bg
= image_spec_value (img->spec, QCbackground, NULL);
-
if (STRINGP (specified_bg))
/* The user specified `:background', use that. */
{
png_color_16 user_bg;
bzero (&user_bg, sizeof user_bg);
- user_bg.red = color.red;
- user_bg.green = color.green;
- user_bg.blue = color.blue;
+ user_bg.red = 256 * GetRValue (color);
+ user_bg.green = 256 * GetGValue (color);
+ user_bg.blue = 256 * GetBValue (color);
- png_set_background (png_ptr, &user_bg,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ fn_png_set_background (png_ptr, &user_bg,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
}
- else if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+ else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg))
/* Image contains a background color with which to
combine the image. */
- png_set_background (png_ptr, image_background,
- PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ fn_png_set_background (png_ptr, image_bg,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
{
/* Image does not contain a background color with which
to combine the image data via an alpha channel. Use
the frame's background instead. */
- XColor color;
- Colormap cmap;
+ COLORREF color;
png_color_16 frame_background;
+ color = FRAME_BACKGROUND_PIXEL (f);
+#if 0 /* TODO : Colormap support. */
+ Colormap cmap;
cmap = FRAME_X_COLORMAP (f);
- color.pixel = FRAME_BACKGROUND_PIXEL (f);
x_query_color (f, &color);
+#endif
bzero (&frame_background, sizeof frame_background);
- frame_background.red = color.red;
- frame_background.green = color.green;
- frame_background.blue = color.blue;
+ frame_background.red = 256 * GetRValue (color);
+ frame_background.green = 256 * GetGValue (color);
+ frame_background.blue = 256 * GetBValue (color);
- png_set_background (png_ptr, &frame_background,
- PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ fn_png_set_background (png_ptr, &frame_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
}
}
/* Update info structure. */
- png_read_update_info (png_ptr, info_ptr);
+ fn_png_read_update_info (png_ptr, info_ptr);
/* Get number of channels. Valid values are 1 for grayscale images
and images with a palette, 2 for grayscale images with transparency
information (alpha channel), 3 for RGB images, and 4 for RGB
images with alpha channel, i.e. RGBA. If conversions above were
sufficient we should only have 3 or 4 channels here. */
- channels = png_get_channels (png_ptr, info_ptr);
+ channels = fn_png_get_channels (png_ptr, info_ptr);
xassert (channels == 3 || channels == 4);
/* Number of bytes needed for one row of the image. */
- row_bytes = png_get_rowbytes (png_ptr, info_ptr);
+ row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
/* Allocate memory for the image. */
pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
rows[i] = pixels + i * row_bytes;
/* Read the entire image. */
- png_read_image (png_ptr, rows);
- png_read_end (png_ptr, info_ptr);
+ fn_png_read_image (png_ptr, rows);
+ fn_png_read_end (png_ptr, info_ptr);
if (fp)
{
fclose (fp);
&mask_img, &img->mask))
{
x_destroy_x_image (ximg);
- XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap);
+ DeleteObject (img->pixmap);
img->pixmap = 0;
goto error;
}
-
/* Fill the X image and mask from PNG data. */
+#if 0 /* TODO: Color tables. */
init_color_table ();
+#endif
for (y = 0; y < height; ++y)
{
{
unsigned r, g, b;
- r = *p++ << 8;
- g = *p++ << 8;
- b = *p++ << 8;
+ r = *p++;
+ g = *p++;
+ b = *p++;
+#if 0 /* TODO: Color tables. */
XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
-
+#else
+ XPutPixel (ximg, x, y, PALETTERGB (r, g, b));
+#endif
/* An alpha channel, aka mask channel, associates variable
transparency with an image. Where other image formats
support binary transparency---fully transparent or fully
overrode it. */
{
png_color_16 *bg;
- if (png_get_bKGD (png_ptr, info_ptr, &bg))
+ if (fn_png_get_bKGD (png_ptr, info_ptr, &bg))
{
+#if 0 /* TODO: Color tables. */
img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
+#else
+ img->background = PALETTERGB (bg->red / 256, bg->green / 256,
+ bg->blue / 256);
+#endif
img->background_valid = 1;
}
}
+#if 0 /* TODO: Color tables. */
/* Remember colors allocated for this image. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
/* Clean up. */
- png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
+ fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
xfree (rows);
xfree (pixels);
};
+/* JPEG library details. */
+DEF_IMGLIB_FN (jpeg_CreateDecompress);
+DEF_IMGLIB_FN (jpeg_start_decompress);
+DEF_IMGLIB_FN (jpeg_finish_decompress);
+DEF_IMGLIB_FN (jpeg_destroy_decompress);
+DEF_IMGLIB_FN (jpeg_read_header);
+DEF_IMGLIB_FN (jpeg_read_scanlines);
+DEF_IMGLIB_FN (jpeg_stdio_src);
+DEF_IMGLIB_FN (jpeg_std_error);
+DEF_IMGLIB_FN (jpeg_resync_to_restart);
+
+static int
+init_jpeg_functions (library)
+ HMODULE library;
+{
+ LOAD_IMGLIB_FN (library, jpeg_finish_decompress);
+ LOAD_IMGLIB_FN (library, jpeg_read_scanlines);
+ LOAD_IMGLIB_FN (library, jpeg_start_decompress);
+ LOAD_IMGLIB_FN (library, jpeg_read_header);
+ LOAD_IMGLIB_FN (library, jpeg_stdio_src);
+ LOAD_IMGLIB_FN (library, jpeg_CreateDecompress);
+ LOAD_IMGLIB_FN (library, jpeg_destroy_decompress);
+ LOAD_IMGLIB_FN (library, jpeg_std_error);
+ LOAD_IMGLIB_FN (library, jpeg_resync_to_restart);
+ return 1;
+}
+
+/* Wrapper since we can't directly assign the function pointer
+ to another function pointer that was declared more completely easily. */
+static boolean
+jpeg_resync_to_restart_wrapper(cinfo, desired)
+ j_decompress_ptr cinfo;
+ int desired;
+{
+ return fn_jpeg_resync_to_restart (cinfo, desired);
+}
+
+
/* Return non-zero if OBJECT is a valid JPEG image specification. */
static int
jmp_buf setjmp_buffer;
};
+
static void
my_error_exit (cinfo)
j_common_ptr cinfo;
longjmp (mgr->setjmp_buffer, 1);
}
+
/* Init source method for JPEG data source manager. Called by
jpeg_read_header() before any data is actually read. See
libjpeg.doc from the JPEG lib distribution. */
src->init_source = our_init_source;
src->fill_input_buffer = our_fill_input_buffer;
src->skip_input_data = our_skip_input_data;
- src->resync_to_restart = jpeg_resync_to_restart; /* Use default method. */
+ src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */
src->term_source = our_term_source;
src->bytes_in_buffer = len;
src->next_input_byte = data;
{
file = x_find_image_file (specified_file);
if (!STRINGP (file))
- {
- image_error ("Cannot find image file `%s'", specified_file, Qnil);
- UNGCPRO;
- return 0;
- }
+ {
+ image_error ("Cannot find image file `%s'", specified_file, Qnil);
+ UNGCPRO;
+ return 0;
+ }
fp = fopen (SDATA (file), "r");
if (fp == NULL)
- {
- image_error ("Cannot open `%s'", file, Qnil);
- UNGCPRO;
- return 0;
- }
+ {
+ image_error ("Cannot open `%s'", file, Qnil);
+ UNGCPRO;
+ return 0;
+ }
}
/* Customize libjpeg's error handling to call my_error_exit when an
- error is detected. This function will perform a longjmp. */
- cinfo.err = jpeg_std_error (&mgr.pub);
+ error is detected. This function will perform a longjmp. */
+ cinfo.err = fn_jpeg_std_error (&mgr.pub);
mgr.pub.error_exit = my_error_exit;
if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
/* Close the input file and destroy the JPEG object. */
if (fp)
- fclose (fp);
- jpeg_destroy_decompress (&cinfo);
+ fclose ((FILE *) fp);
+ fn_jpeg_destroy_decompress (&cinfo);
/* If we already have an XImage, free that. */
x_destroy_x_image (ximg);
}
/* Create the JPEG decompression object. Let it read from fp.
- Read the JPEG image header. */
- jpeg_create_decompress (&cinfo);
+ Read the JPEG image header. */
+ fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo));
if (NILP (specified_data))
- jpeg_stdio_src (&cinfo, fp);
+ fn_jpeg_stdio_src (&cinfo, (FILE *) fp);
else
jpeg_memory_src (&cinfo, SDATA (specified_data),
SBYTES (specified_data));
- jpeg_read_header (&cinfo, TRUE);
+ fn_jpeg_read_header (&cinfo, TRUE);
/* Customize decompression so that color quantization will be used.
- Start decompression. */
+ Start decompression. */
cinfo.quantize_colors = TRUE;
- jpeg_start_decompress (&cinfo);
+ fn_jpeg_start_decompress (&cinfo);
width = img->width = cinfo.output_width;
height = img->height = cinfo.output_height;
/* Create X image and pixmap. */
- if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
- &img->pixmap))
+ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
longjmp (mgr.setjmp_buffer, 2);
/* Allocate colors. When color quantization is used,
else
ir = 0, ig = 0, ib = 0;
+#if 0 /* TODO: Color tables. */
/* Use the color table mechanism because it handles colors that
cannot be allocated nicely. Such colors will be replaced with
a default color, and we don't have to care about which colors
can be freed safely, and which can't. */
init_color_table ();
+#endif
colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
* sizeof *colors);
for (i = 0; i < cinfo.actual_number_of_colors; ++i)
{
- /* Multiply RGB values with 255 because X expects RGB values
- in the range 0..0xffff. */
- int r = cinfo.colormap[ir][i] << 8;
- int g = cinfo.colormap[ig][i] << 8;
- int b = cinfo.colormap[ib][i] << 8;
+ int r = cinfo.colormap[ir][i];
+ int g = cinfo.colormap[ig][i];
+ int b = cinfo.colormap[ib][i];
+#if 0 /* TODO: Color tables. */
colors[i] = lookup_rgb_color (f, r, g, b);
+#else
+ colors[i] = PALETTERGB (r, g, b);
+#endif
}
+#if 0 /* TODO: Color tables. */
/* Remember those colors actually allocated. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
}
/* Read pixels. */
row_stride, 1);
for (y = 0; y < height; ++y)
{
- jpeg_read_scanlines (&cinfo, buffer, 1);
+ fn_jpeg_read_scanlines (&cinfo, buffer, 1);
for (x = 0; x < cinfo.output_width; ++x)
XPutPixel (ximg, x, y, colors[buffer[0][x]]);
}
/* Clean up. */
- jpeg_finish_decompress (&cinfo);
- jpeg_destroy_decompress (&cinfo);
+ fn_jpeg_finish_decompress (&cinfo);
+ fn_jpeg_destroy_decompress (&cinfo);
if (fp)
- fclose (fp);
+ fclose ((FILE *) fp);
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
/* Put the image into the pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
- UNBLOCK_INPUT;
UNGCPRO;
return 1;
}
NULL
};
+/* TIFF library details. */
+DEF_IMGLIB_FN (TIFFSetErrorHandler);
+DEF_IMGLIB_FN (TIFFSetWarningHandler);
+DEF_IMGLIB_FN (TIFFOpen);
+DEF_IMGLIB_FN (TIFFClientOpen);
+DEF_IMGLIB_FN (TIFFGetField);
+DEF_IMGLIB_FN (TIFFReadRGBAImage);
+DEF_IMGLIB_FN (TIFFClose);
+
+static int
+init_tiff_functions (library)
+ HMODULE library;
+{
+ LOAD_IMGLIB_FN (library, TIFFSetErrorHandler);
+ LOAD_IMGLIB_FN (library, TIFFSetWarningHandler);
+ LOAD_IMGLIB_FN (library, TIFFOpen);
+ LOAD_IMGLIB_FN (library, TIFFClientOpen);
+ LOAD_IMGLIB_FN (library, TIFFGetField);
+ LOAD_IMGLIB_FN (library, TIFFReadRGBAImage);
+ LOAD_IMGLIB_FN (library, TIFFClose);
+ return 1;
+}
/* Return non-zero if OBJECT is a valid TIFF image specification. */
file = Qnil;
GCPRO1 (file);
- TIFFSetErrorHandler (tiff_error_handler);
- TIFFSetWarningHandler (tiff_warning_handler);
+ fn_TIFFSetErrorHandler (tiff_error_handler);
+ fn_TIFFSetWarningHandler (tiff_warning_handler);
if (NILP (specified_data))
{
}
/* Try to open the image file. */
- tiff = TIFFOpen (SDATA (file), "r");
+ tiff = fn_TIFFOpen (SDATA (file), "r");
if (tiff == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
- tiff = TIFFClientOpen ("memory_source", "r", &memsrc,
- (TIFFReadWriteProc) tiff_read_from_memory,
- (TIFFReadWriteProc) tiff_write_from_memory,
- tiff_seek_in_memory,
- tiff_close_memory,
- tiff_size_of_memory,
- tiff_mmap_memory,
- tiff_unmap_memory);
+ tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc,
+ (TIFFReadWriteProc) tiff_read_from_memory,
+ (TIFFReadWriteProc) tiff_write_from_memory,
+ tiff_seek_in_memory,
+ tiff_close_memory,
+ tiff_size_of_memory,
+ tiff_mmap_memory,
+ tiff_unmap_memory);
if (!tiff)
{
/* Get width and height of the image, and allocate a raster buffer
of width x height 32-bit values. */
- TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
- TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
+ fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
+ fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
buf = (uint32 *) xmalloc (width * height * sizeof *buf);
- rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
- TIFFClose (tiff);
+ rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
+ fn_TIFFClose (tiff);
if (!rc)
{
image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
return 0;
}
+#if 0 /* TODO: Color tables. */
/* Initialize the color table. */
init_color_table ();
+#endif
/* Process the pixel raster. Origin is in the lower-left corner. */
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
{
uint32 abgr = row[x];
- int r = TIFFGetR (abgr) << 8;
- int g = TIFFGetG (abgr) << 8;
- int b = TIFFGetB (abgr) << 8;
+ int r = TIFFGetR (abgr);
+ int g = TIFFGetG (abgr);
+ int b = TIFFGetB (abgr);
+#if 0 /* TODO: Color tables. */
XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
+#else
+ XPutPixel (ximg, x, height - 1 - y, PALETTERGB (r, g, b));
+#endif
}
}
+#if 0 /* TODO: Color tables. */
/* Remember the colors allocated for the image. Free the color table. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
img->width = width;
img->height = height;
#if HAVE_GIF
+#define DrawText gif_DrawText
#include <gif_lib.h>
+#undef DrawText
static int gif_image_p P_ ((Lisp_Object object));
static int gif_load P_ ((struct frame *f, struct image *img));
NULL
};
+
+/* GIF library details. */
+DEF_IMGLIB_FN (DGifCloseFile);
+DEF_IMGLIB_FN (DGifSlurp);
+DEF_IMGLIB_FN (DGifOpen);
+DEF_IMGLIB_FN (DGifOpenFileName);
+
+static int
+init_gif_functions (library)
+ HMODULE library;
+{
+ LOAD_IMGLIB_FN (library, DGifCloseFile);
+ LOAD_IMGLIB_FN (library, DGifSlurp);
+ LOAD_IMGLIB_FN (library, DGifOpen);
+ LOAD_IMGLIB_FN (library, DGifOpenFileName);
+ return 1;
+}
+
+
/* Return non-zero if OBJECT is a valid GIF image specification. */
static int
}
/* Open the GIF file. */
- gif = DGifOpenFileName (SDATA (file));
+ gif = fn_DGifOpenFileName (SDATA (file));
if (gif == NULL)
{
image_error ("Cannot open `%s'", file, Qnil);
memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
- gif = DGifOpen(&memsrc, gif_read_from_memory);
+ gif = fn_DGifOpen(&memsrc, gif_read_from_memory);
if (!gif)
{
image_error ("Cannot open memory source `%s'", img->spec, Qnil);
}
/* Read entire contents. */
- rc = DGifSlurp (gif);
+ rc = fn_DGifSlurp (gif);
if (rc == GIF_ERROR)
{
image_error ("Error reading `%s'", img->spec, Qnil);
- DGifCloseFile (gif);
+ fn_DGifCloseFile (gif);
UNGCPRO;
return 0;
}
{
image_error ("Invalid image number `%s' in image `%s'",
image, img->spec);
- DGifCloseFile (gif);
+ fn_DGifCloseFile (gif);
UNGCPRO;
return 0;
}
- width = img->width = gif->SWidth;
- height = img->height = gif->SHeight;
+ width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width);
+ height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height);
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
- DGifCloseFile (gif);
+ fn_DGifCloseFile (gif);
UNGCPRO;
return 0;
}
gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap;
if (!gif_color_map)
gif_color_map = gif->SColorMap;
+#if 0 /* TODO: Color tables */
init_color_table ();
+#endif
bzero (pixel_colors, sizeof pixel_colors);
for (i = 0; i < gif_color_map->ColorCount; ++i)
{
- int r = gif_color_map->Colors[i].Red << 8;
- int g = gif_color_map->Colors[i].Green << 8;
- int b = gif_color_map->Colors[i].Blue << 8;
+ int r = gif_color_map->Colors[i].Red;
+ int g = gif_color_map->Colors[i].Green;
+ int b = gif_color_map->Colors[i].Blue;
+#if 0 /* TODO: Color tables */
pixel_colors[i] = lookup_rgb_color (f, r, g, b);
+#else
+ pixel_colors[i] = PALETTERGB (r, g, b);
+#endif
}
+#if 0 /* TODO: Color tables */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
/* Clear the part of the screen image that are not covered by
the image from the GIF file. Full animated GIF support
}
}
- DGifCloseFile (gif);
+ fn_DGifCloseFile (gif);
/* Maybe fill in the background field while we have ximg handy. */
if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
Lisp_Object Qpostscript;
+/* Keyword symbols. */
+
+Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height;
+
#ifdef HAVE_GHOSTSCRIPT
static int gs_image_p P_ ((Lisp_Object object));
static int gs_load P_ ((struct frame *f, struct image *img));
void
syms_of_w32fns ()
{
- HMODULE user32_lib = GetModuleHandle ("user32.dll");
-
+ globals_of_w32fns ();
/* This is zero if not using MS-Windows. */
w32_in_use = 0;
-
- /* TrackMouseEvent not available in all versions of Windows, so must load
- it dynamically. Do it once, here, instead of every time it is used. */
- track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
track_mouse_window = NULL;
w32_visible_system_caret_hwnd = NULL;
init_x_parm_symbols ();
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
- doc: /* List of directories to search for bitmap files for w32. */);
+ doc: /* List of directories to search for window system bitmap files. */);
Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
staticpro (&QCrelief);
Qpostscript = intern ("postscript");
staticpro (&Qpostscript);
-#if 0 /* TODO: These need entries at top of file. */
QCloader = intern (":loader");
staticpro (&QCloader);
QCbounding_box = intern (":bounding-box");
staticpro (&QCpt_width);
QCpt_height = intern (":pt-height");
staticpro (&QCpt_height);
-#endif
QCindex = intern (":index");
staticpro (&QCindex);
Qpbm = intern ("pbm");
}
-void
-init_xfns ()
+/*
+ globals_of_w32fns is used to initialize those global variables that
+ must always be initialized on startup even when the global variable
+ initialized is non zero (see the function main in emacs.c).
+ globals_of_w32fns is called from syms_of_w32fns when the global
+ variable initialized is 0 and directly from main when initialized
+ is non zero.
+ */
+void globals_of_w32fns ()
{
- image_types = NULL;
- Vimage_types = Qnil;
+ HMODULE user32_lib = GetModuleHandle ("user32.dll");
+ /*
+ TrackMouseEvent not available in all versions of Windows, so must load
+ it dynamically. Do it once, here, instead of every time it is used.
+ */
+ track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent");
+}
- define_image_type (&pbm_type);
- define_image_type (&xbm_type);
-#if 0 /* TODO : Image support for W32 */
- define_image_type (&gs_type);
-#endif
+/* Initialize image types. Based on which libraries are available. */
+static void
+init_external_image_libraries ()
+{
+ HINSTANCE library;
#if HAVE_XPM
- define_image_type (&xpm_type);
+ if ((library = LoadLibrary ("libXpm.dll")))
+ {
+ if (init_xpm_functions (library))
+ define_image_type (&xpm_type);
+ }
+
#endif
#if HAVE_JPEG
- define_image_type (&jpeg_type);
+ /* Try loading jpeg library under probable names. */
+ if ((library = LoadLibrary ("libjpeg.dll"))
+ || (library = LoadLibrary ("jpeg-62.dll"))
+ || (library = LoadLibrary ("jpeg.dll")))
+ {
+ if (init_jpeg_functions (library))
+ define_image_type (&jpeg_type);
+ }
#endif
#if HAVE_TIFF
- define_image_type (&tiff_type);
+ if (library = LoadLibrary ("libtiff.dll"))
+ {
+ if (init_tiff_functions (library))
+ define_image_type (&tiff_type);
+ }
#endif
#if HAVE_GIF
- define_image_type (&gif_type);
+ if (library = LoadLibrary ("libungif.dll"))
+ {
+ if (init_gif_functions (library))
+ define_image_type (&gif_type);
+ }
#endif
#if HAVE_PNG
- define_image_type (&png_type);
+ /* Ensure zlib is loaded. Try debug version first. */
+ if (!LoadLibrary ("zlibd.dll"))
+ LoadLibrary ("zlib.dll");
+
+ /* Try loading libpng under probable names. */
+ if ((library = LoadLibrary ("libpng13d.dll"))
+ || (library = LoadLibrary ("libpng13.dll"))
+ || (library = LoadLibrary ("libpng12d.dll"))
+ || (library = LoadLibrary ("libpng12.dll"))
+ || (library = LoadLibrary ("libpng.dll")))
+ {
+ if (init_png_functions (library))
+ define_image_type (&png_type);
+ }
+#endif
+}
+
+void
+init_xfns ()
+{
+ image_types = NULL;
+ Vimage_types = Qnil;
+
+ define_image_type (&pbm_type);
+ define_image_type (&xbm_type);
+
+#if 0 /* TODO : Ghostscript support for W32 */
+ define_image_type (&gs_type);
#endif
+
+ /* Image types that rely on external libraries are loaded dynamically
+ if the library is available. */
+ init_external_image_libraries ();
}
#undef abort