52 |
#include <shellapi.h> |
#include <shellapi.h> |
53 |
#include <ctype.h> |
#include <ctype.h> |
54 |
|
|
55 |
|
#include <dlgs.h> |
56 |
|
#define FILE_NAME_TEXT_FIELD edt1 |
57 |
|
|
58 |
|
void syms_of_w32fns (); |
59 |
|
void globals_of_w32fns (); |
60 |
|
static void init_external_image_libraries (); |
61 |
|
|
62 |
extern void free_frame_menubar (); |
extern void free_frame_menubar (); |
|
extern void x_compute_fringe_widths P_ ((struct frame *, int)); |
|
63 |
extern double atof (); |
extern double atof (); |
64 |
extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object)); |
extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object)); |
65 |
extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT)); |
extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT)); |
67 |
|
|
68 |
extern int quit_char; |
extern int quit_char; |
69 |
|
|
|
/* A definition of XColor for non-X frames. */ |
|
|
#ifndef HAVE_X_WINDOWS |
|
|
typedef struct { |
|
|
unsigned long pixel; |
|
|
unsigned short red, green, blue; |
|
|
char flags; |
|
|
char pad; |
|
|
} XColor; |
|
|
#endif |
|
|
|
|
70 |
extern char *lispy_function_keys[]; |
extern char *lispy_function_keys[]; |
71 |
|
|
72 |
/* The gray bitmap `bitmaps/gray'. This is done because w32term.c uses |
/* The gray bitmap `bitmaps/gray'. This is done because w32term.c uses |
141 |
/* Flag to indicate if XBUTTON events should be passed on to Windows. */ |
/* Flag to indicate if XBUTTON events should be passed on to Windows. */ |
142 |
int w32_pass_extra_mouse_buttons_to_system; |
int w32_pass_extra_mouse_buttons_to_system; |
143 |
|
|
|
/* The name we're using in resource queries. */ |
|
|
Lisp_Object Vx_resource_name; |
|
|
|
|
144 |
/* Non nil if no window manager is in use. */ |
/* Non nil if no window manager is in use. */ |
145 |
Lisp_Object Vx_no_window_manager; |
Lisp_Object Vx_no_window_manager; |
146 |
|
|
152 |
over text or in the modeline. */ |
over text or in the modeline. */ |
153 |
|
|
154 |
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape; |
Lisp_Object Vx_pointer_shape, Vx_nontext_pointer_shape, Vx_mode_pointer_shape; |
155 |
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; |
156 |
|
|
157 |
/* The shape when over mouse-sensitive text. */ |
/* The shape when over mouse-sensitive text. */ |
158 |
|
|
159 |
Lisp_Object Vx_sensitive_text_pointer_shape; |
Lisp_Object Vx_sensitive_text_pointer_shape; |
160 |
|
|
161 |
|
#ifndef IDC_HAND |
162 |
|
#define IDC_HAND MAKEINTRESOURCE(32649) |
163 |
|
#endif |
164 |
|
|
165 |
/* Color of chars displayed in cursor box. */ |
/* Color of chars displayed in cursor box. */ |
166 |
|
|
167 |
Lisp_Object Vx_cursor_fore_pixel; |
Lisp_Object Vx_cursor_fore_pixel; |
196 |
#define VIETNAMESE_CHARSET 163 |
#define VIETNAMESE_CHARSET 163 |
197 |
#endif |
#endif |
198 |
|
|
|
Lisp_Object Qauto_raise; |
|
|
Lisp_Object Qauto_lower; |
|
|
Lisp_Object Qbar, Qhbar; |
|
|
Lisp_Object Qborder_color; |
|
|
Lisp_Object Qborder_width; |
|
|
Lisp_Object Qbox; |
|
|
Lisp_Object Qcursor_color; |
|
|
Lisp_Object Qcursor_type; |
|
|
Lisp_Object Qgeometry; |
|
|
Lisp_Object Qicon_left; |
|
|
Lisp_Object Qicon_top; |
|
|
Lisp_Object Qicon_type; |
|
|
Lisp_Object Qicon_name; |
|
|
Lisp_Object Qinternal_border_width; |
|
|
Lisp_Object Qleft; |
|
|
Lisp_Object Qright; |
|
|
Lisp_Object Qmouse_color; |
|
199 |
Lisp_Object Qnone; |
Lisp_Object Qnone; |
|
Lisp_Object Qparent_id; |
|
|
Lisp_Object Qscroll_bar_width; |
|
200 |
Lisp_Object Qsuppress_icon; |
Lisp_Object Qsuppress_icon; |
201 |
Lisp_Object Qundefined_color; |
Lisp_Object Qundefined_color; |
|
Lisp_Object Qvertical_scroll_bars; |
|
|
Lisp_Object Qvisibility; |
|
|
Lisp_Object Qwindow_id; |
|
|
Lisp_Object Qx_frame_parameter; |
|
|
Lisp_Object Qx_resource_name; |
|
|
Lisp_Object Quser_position; |
|
|
Lisp_Object Quser_size; |
|
|
Lisp_Object Qscreen_gamma; |
|
|
Lisp_Object Qline_spacing; |
|
202 |
Lisp_Object Qcenter; |
Lisp_Object Qcenter; |
203 |
Lisp_Object Qcancel_timer; |
Lisp_Object Qcancel_timer; |
204 |
Lisp_Object Qhyper; |
Lisp_Object Qhyper; |
239 |
Lisp_Object Qw32_charset_unicode; |
Lisp_Object Qw32_charset_unicode; |
240 |
#endif |
#endif |
241 |
|
|
|
Lisp_Object Qfullscreen; |
|
|
Lisp_Object Qfullwidth; |
|
|
Lisp_Object Qfullheight; |
|
|
Lisp_Object Qfullboth; |
|
|
|
|
|
extern Lisp_Object Qtop; |
|
|
extern Lisp_Object Qdisplay; |
|
|
|
|
242 |
/* State variables for emulating a three button mouse. */ |
/* State variables for emulating a three button mouse. */ |
243 |
#define LMOUSE 1 |
#define LMOUSE 1 |
244 |
#define MMOUSE 2 |
#define MMOUSE 2 |
252 |
|
|
253 |
/* Window that is tracking the mouse. */ |
/* Window that is tracking the mouse. */ |
254 |
static HWND track_mouse_window; |
static HWND track_mouse_window; |
255 |
FARPROC track_mouse_event_fn; |
|
256 |
|
typedef BOOL (WINAPI * TrackMouseEvent_Proc) ( |
257 |
|
IN OUT LPTRACKMOUSEEVENT lpEventTrack |
258 |
|
); |
259 |
|
|
260 |
|
TrackMouseEvent_Proc track_mouse_event_fn=NULL; |
261 |
|
|
262 |
/* W95 mousewheel handler */ |
/* W95 mousewheel handler */ |
263 |
unsigned int msh_mousewheel = 0; |
unsigned int msh_mousewheel = 0; |
264 |
|
|
265 |
/* Timers */ |
/* Timers */ |
266 |
#define MOUSE_BUTTON_ID 1 |
#define MOUSE_BUTTON_ID 1 |
273 |
|
|
274 |
/* The below are defined in frame.c. */ |
/* The below are defined in frame.c. */ |
275 |
|
|
|
extern Lisp_Object Qheight, Qminibuffer, Qname, Qonly, Qwidth; |
|
|
extern Lisp_Object Qunsplittable, Qmenu_bar_lines, Qbuffer_predicate, Qtitle; |
|
|
extern Lisp_Object Qtool_bar_lines; |
|
|
|
|
276 |
extern Lisp_Object Vwindow_system_version; |
extern Lisp_Object Vwindow_system_version; |
277 |
|
|
|
Lisp_Object Qface_set_after_frame_default; |
|
|
|
|
278 |
#ifdef GLYPH_DEBUG |
#ifdef GLYPH_DEBUG |
279 |
int image_cache_refcount, dpyinfo_refcount; |
int image_cache_refcount, dpyinfo_refcount; |
280 |
#endif |
#endif |
304 |
|
|
305 |
/* Nonzero if we can use mouse menus. |
/* Nonzero if we can use mouse menus. |
306 |
You should not call this unless HAVE_MENUS is defined. */ |
You should not call this unless HAVE_MENUS is defined. */ |
307 |
|
|
308 |
int |
int |
309 |
have_menus_p () |
have_menus_p () |
310 |
{ |
{ |
329 |
return f; |
return f; |
330 |
} |
} |
331 |
|
|
332 |
/* Let the user specify an display with a frame. |
/* Let the user specify a display with a frame. |
333 |
nil stands for the selected frame--or, if that is not a w32 frame, |
nil stands for the selected frame--or, if that is not a w32 frame, |
334 |
the first display on the list. */ |
the first display on the list. */ |
335 |
|
|
336 |
static struct w32_display_info * |
struct w32_display_info * |
337 |
check_x_display_info (frame) |
check_x_display_info (frame) |
338 |
Lisp_Object frame; |
Lisp_Object frame; |
339 |
{ |
{ |
340 |
if (NILP (frame)) |
if (NILP (frame)) |
341 |
{ |
{ |
342 |
struct frame *sf = XFRAME (selected_frame); |
struct frame *sf = XFRAME (selected_frame); |
343 |
|
|
344 |
if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf)) |
if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf)) |
345 |
return FRAME_W32_DISPLAY_INFO (sf); |
return FRAME_W32_DISPLAY_INFO (sf); |
346 |
else |
else |
528 |
{ |
{ |
529 |
if (dpyinfo->bitmaps[id].refcount |
if (dpyinfo->bitmaps[id].refcount |
530 |
&& dpyinfo->bitmaps[id].file |
&& dpyinfo->bitmaps[id].file |
531 |
&& !strcmp (dpyinfo->bitmaps[id].file, (char *) XSTRING (file)->data)) |
&& !strcmp (dpyinfo->bitmaps[id].file, (char *) SDATA (file))) |
532 |
{ |
{ |
533 |
++dpyinfo->bitmaps[id].refcount; |
++dpyinfo->bitmaps[id].refcount; |
534 |
return id + 1; |
return id + 1; |
541 |
return -1; |
return -1; |
542 |
emacs_close (fd); |
emacs_close (fd); |
543 |
|
|
544 |
filename = (char *) XSTRING (found)->data; |
filename = (char *) SDATA (found); |
545 |
|
|
546 |
hinst = LoadLibraryEx (filename, NULL, LOAD_LIBRARY_AS_DATAFILE); |
hinst = LoadLibraryEx (filename, NULL, LOAD_LIBRARY_AS_DATAFILE); |
547 |
|
|
548 |
if (hinst == NULL) |
if (hinst == NULL) |
549 |
return -1; |
return -1; |
550 |
|
|
551 |
|
|
552 |
result = XReadBitmapFile (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
result = XReadBitmapFile (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
553 |
filename, &width, &height, &bitmap, &xhot, &yhot); |
filename, &width, &height, &bitmap, &xhot, &yhot); |
554 |
if (result != BitmapSuccess) |
if (result != BitmapSuccess) |
557 |
id = x_allocate_bitmap_record (f); |
id = x_allocate_bitmap_record (f); |
558 |
dpyinfo->bitmaps[id - 1].pixmap = bitmap; |
dpyinfo->bitmaps[id - 1].pixmap = bitmap; |
559 |
dpyinfo->bitmaps[id - 1].refcount = 1; |
dpyinfo->bitmaps[id - 1].refcount = 1; |
560 |
dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (XSTRING (file)->size + 1); |
dpyinfo->bitmaps[id - 1].file = (char *) xmalloc (SCHARS (file) + 1); |
561 |
dpyinfo->bitmaps[id - 1].depth = 1; |
dpyinfo->bitmaps[id - 1].depth = 1; |
562 |
dpyinfo->bitmaps[id - 1].height = height; |
dpyinfo->bitmaps[id - 1].height = height; |
563 |
dpyinfo->bitmaps[id - 1].width = width; |
dpyinfo->bitmaps[id - 1].width = width; |
564 |
strcpy (dpyinfo->bitmaps[id - 1].file, XSTRING (file)->data); |
strcpy (dpyinfo->bitmaps[id - 1].file, SDATA (file)); |
565 |
|
|
566 |
return id; |
return id; |
567 |
#endif /* TODO */ |
#endif /* TODO */ |
610 |
dpyinfo->bitmaps_last = 0; |
dpyinfo->bitmaps_last = 0; |
611 |
} |
} |
612 |
|
|
|
/* Connect the frame-parameter names for W32 frames |
|
|
to the ways of passing the parameter values to the window system. |
|
|
|
|
|
The name of a parameter, as a Lisp symbol, |
|
|
has an `x-frame-parameter' property which is an integer in Lisp |
|
|
but can be interpreted as an `enum x_frame_parm' in C. */ |
|
|
|
|
|
enum x_frame_parm |
|
|
{ |
|
|
X_PARM_FOREGROUND_COLOR, |
|
|
X_PARM_BACKGROUND_COLOR, |
|
|
X_PARM_MOUSE_COLOR, |
|
|
X_PARM_CURSOR_COLOR, |
|
|
X_PARM_BORDER_COLOR, |
|
|
X_PARM_ICON_TYPE, |
|
|
X_PARM_FONT, |
|
|
X_PARM_BORDER_WIDTH, |
|
|
X_PARM_INTERNAL_BORDER_WIDTH, |
|
|
X_PARM_NAME, |
|
|
X_PARM_AUTORAISE, |
|
|
X_PARM_AUTOLOWER, |
|
|
X_PARM_VERT_SCROLL_BAR, |
|
|
X_PARM_VISIBILITY, |
|
|
X_PARM_MENU_BAR_LINES |
|
|
}; |
|
|
|
|
|
|
|
|
struct x_frame_parm_table |
|
|
{ |
|
|
char *name; |
|
|
void (*setter) P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
}; |
|
|
|
|
613 |
BOOL my_show_window P_ ((struct frame *, HWND, int)); |
BOOL my_show_window P_ ((struct frame *, HWND, int)); |
614 |
void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT)); |
void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT)); |
615 |
static Lisp_Object unwind_create_frame P_ ((Lisp_Object)); |
static Lisp_Object unwind_create_frame P_ ((Lisp_Object)); |
616 |
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object)); |
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object)); |
617 |
static void x_change_window_heights P_ ((Lisp_Object, int)); |
|
618 |
/* TODO: Native Input Method support; see x_create_im. */ |
/* TODO: Native Input Method support; see x_create_im. */ |
619 |
void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_foreground_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
static void x_set_line_spacing P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
static void x_set_fullscreen P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
620 |
void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
621 |
void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
622 |
void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
624 |
void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_cursor_type P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
625 |
void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_icon_type P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
626 |
void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_icon_name P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
void x_set_font P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
static void x_set_fringe_width P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
void x_set_border_width P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
void x_set_internal_border_width P_ ((struct frame *, Lisp_Object, |
|
|
Lisp_Object)); |
|
627 |
void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_explicitly_set_name P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
void x_set_autoraise P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
void x_set_autolower P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
|
void x_set_vertical_scroll_bars P_ ((struct frame *, Lisp_Object, |
|
|
Lisp_Object)); |
|
|
void x_set_visibility P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
628 |
void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_menu_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
void x_set_scroll_bar_width P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
629 |
void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_title P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
void x_set_unsplittable P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
630 |
void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
void x_set_tool_bar_lines P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
static void x_set_screen_gamma P_ ((struct frame *, Lisp_Object, Lisp_Object)); |
|
631 |
static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, |
static void x_edge_detection P_ ((struct frame *, struct image *, Lisp_Object, |
632 |
Lisp_Object)); |
Lisp_Object)); |
633 |
|
|
|
static struct x_frame_parm_table x_frame_parms[] = |
|
|
{ |
|
|
{"auto-raise", x_set_autoraise}, |
|
|
{"auto-lower", x_set_autolower}, |
|
|
{"background-color", x_set_background_color}, |
|
|
{"border-color", x_set_border_color}, |
|
|
{"border-width", x_set_border_width}, |
|
|
{"cursor-color", x_set_cursor_color}, |
|
|
{"cursor-type", x_set_cursor_type}, |
|
|
{"font", x_set_font}, |
|
|
{"foreground-color", x_set_foreground_color}, |
|
|
{"icon-name", x_set_icon_name}, |
|
|
{"icon-type", x_set_icon_type}, |
|
|
{"internal-border-width", x_set_internal_border_width}, |
|
|
{"menu-bar-lines", x_set_menu_bar_lines}, |
|
|
{"mouse-color", x_set_mouse_color}, |
|
|
{"name", x_explicitly_set_name}, |
|
|
{"scroll-bar-width", x_set_scroll_bar_width}, |
|
|
{"title", x_set_title}, |
|
|
{"unsplittable", x_set_unsplittable}, |
|
|
{"vertical-scroll-bars", x_set_vertical_scroll_bars}, |
|
|
{"visibility", x_set_visibility}, |
|
|
{"tool-bar-lines", x_set_tool_bar_lines}, |
|
|
{"screen-gamma", x_set_screen_gamma}, |
|
|
{"line-spacing", x_set_line_spacing}, |
|
|
{"left-fringe", x_set_fringe_width}, |
|
|
{"right-fringe", x_set_fringe_width}, |
|
|
{"fullscreen", x_set_fullscreen}, |
|
|
}; |
|
|
|
|
|
/* Attach the `x-frame-parameter' properties to |
|
|
the Lisp symbol names of parameters relevant to W32. */ |
|
|
|
|
|
void |
|
|
init_x_parm_symbols () |
|
|
{ |
|
|
int i; |
|
634 |
|
|
|
for (i = 0; i < sizeof (x_frame_parms) / sizeof (x_frame_parms[0]); i++) |
|
|
Fput (intern (x_frame_parms[i].name), Qx_frame_parameter, |
|
|
make_number (i)); |
|
|
} |
|
635 |
|
|
|
/* Really try to move where we want to be in case of fullscreen. Some WMs |
|
|
moves the window where we tell them. Some (mwm, twm) moves the outer |
|
|
window manager window there instead. |
|
|
Try to compensate for those WM here. */ |
|
|
static void |
|
|
x_fullscreen_move (f, new_top, new_left) |
|
|
struct frame *f; |
|
|
int new_top; |
|
|
int new_left; |
|
|
{ |
|
|
if (new_top != f->output_data.w32->top_pos |
|
|
|| new_left != f->output_data.w32->left_pos) |
|
|
{ |
|
|
int move_x = new_left; |
|
|
int move_y = new_top; |
|
|
|
|
|
f->output_data.w32->want_fullscreen |= FULLSCREEN_MOVE_WAIT; |
|
|
x_set_offset (f, move_x, move_y, 1); |
|
|
} |
|
|
} |
|
|
|
|
|
/* Change the parameters of frame F as specified by ALIST. |
|
|
If a parameter is not specially recognized, do nothing; |
|
|
otherwise call the `x_set_...' function for that parameter. */ |
|
|
|
|
|
void |
|
|
x_set_frame_parameters (f, alist) |
|
|
FRAME_PTR f; |
|
|
Lisp_Object alist; |
|
|
{ |
|
|
Lisp_Object tail; |
|
|
|
|
|
/* If both of these parameters are present, it's more efficient to |
|
|
set them both at once. So we wait until we've looked at the |
|
|
entire list before we set them. */ |
|
|
int width, height; |
|
|
|
|
|
/* Same here. */ |
|
|
Lisp_Object left, top; |
|
|
|
|
|
/* Same with these. */ |
|
|
Lisp_Object icon_left, icon_top; |
|
|
|
|
|
/* Record in these vectors all the parms specified. */ |
|
|
Lisp_Object *parms; |
|
|
Lisp_Object *values; |
|
|
int i, p; |
|
|
int left_no_change = 0, top_no_change = 0; |
|
|
int icon_left_no_change = 0, icon_top_no_change = 0; |
|
|
int fullscreen_is_being_set = 0; |
|
|
|
|
|
struct gcpro gcpro1, gcpro2; |
|
|
|
|
|
i = 0; |
|
|
for (tail = alist; CONSP (tail); tail = Fcdr (tail)) |
|
|
i++; |
|
|
|
|
|
parms = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); |
|
|
values = (Lisp_Object *) alloca (i * sizeof (Lisp_Object)); |
|
|
|
|
|
/* Extract parm names and values into those vectors. */ |
|
|
|
|
|
i = 0; |
|
|
for (tail = alist; CONSP (tail); tail = Fcdr (tail)) |
|
|
{ |
|
|
Lisp_Object elt; |
|
|
|
|
|
elt = Fcar (tail); |
|
|
parms[i] = Fcar (elt); |
|
|
values[i] = Fcdr (elt); |
|
|
i++; |
|
|
} |
|
|
/* TAIL and ALIST are not used again below here. */ |
|
|
alist = tail = Qnil; |
|
|
|
|
|
GCPRO2 (*parms, *values); |
|
|
gcpro1.nvars = i; |
|
|
gcpro2.nvars = i; |
|
|
|
|
|
/* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP, |
|
|
because their values appear in VALUES and strings are not valid. */ |
|
|
top = left = Qunbound; |
|
|
icon_left = icon_top = Qunbound; |
|
|
|
|
|
/* Provide default values for HEIGHT and WIDTH. */ |
|
|
if (FRAME_NEW_WIDTH (f)) |
|
|
width = FRAME_NEW_WIDTH (f); |
|
|
else |
|
|
width = FRAME_WIDTH (f); |
|
|
|
|
|
if (FRAME_NEW_HEIGHT (f)) |
|
|
height = FRAME_NEW_HEIGHT (f); |
|
|
else |
|
|
height = FRAME_HEIGHT (f); |
|
|
|
|
|
/* Process foreground_color and background_color before anything else. |
|
|
They are independent of other properties, but other properties (e.g., |
|
|
cursor_color) are dependent upon them. */ |
|
|
/* Process default font as well, since fringe widths depends on it. */ |
|
|
for (p = 0; p < i; p++) |
|
|
{ |
|
|
Lisp_Object prop, val; |
|
|
|
|
|
prop = parms[p]; |
|
|
val = values[p]; |
|
|
if (EQ (prop, Qforeground_color) |
|
|
|| EQ (prop, Qbackground_color) |
|
|
|| EQ (prop, Qfont) |
|
|
|| EQ (prop, Qfullscreen)) |
|
|
{ |
|
|
register Lisp_Object param_index, old_value; |
|
|
|
|
|
old_value = get_frame_param (f, prop); |
|
|
fullscreen_is_being_set |= EQ (prop, Qfullscreen); |
|
|
|
|
|
if (NILP (Fequal (val, old_value))) |
|
|
{ |
|
|
store_frame_param (f, prop, val); |
|
|
|
|
|
param_index = Fget (prop, Qx_frame_parameter); |
|
|
if (NATNUMP (param_index) |
|
|
&& (XFASTINT (param_index) |
|
|
< sizeof (x_frame_parms)/sizeof (x_frame_parms[0]))) |
|
|
(*x_frame_parms[XINT (param_index)].setter)(f, val, old_value); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
/* Now process them in reverse of specified order. */ |
|
|
for (i--; i >= 0; i--) |
|
|
{ |
|
|
Lisp_Object prop, val; |
|
|
|
|
|
prop = parms[i]; |
|
|
val = values[i]; |
|
|
|
|
|
if (EQ (prop, Qwidth) && NUMBERP (val)) |
|
|
width = XFASTINT (val); |
|
|
else if (EQ (prop, Qheight) && NUMBERP (val)) |
|
|
height = XFASTINT (val); |
|
|
else if (EQ (prop, Qtop)) |
|
|
top = val; |
|
|
else if (EQ (prop, Qleft)) |
|
|
left = val; |
|
|
else if (EQ (prop, Qicon_top)) |
|
|
icon_top = val; |
|
|
else if (EQ (prop, Qicon_left)) |
|
|
icon_left = val; |
|
|
else if (EQ (prop, Qforeground_color) |
|
|
|| EQ (prop, Qbackground_color) |
|
|
|| EQ (prop, Qfont) |
|
|
|| EQ (prop, Qfullscreen)) |
|
|
/* Processed above. */ |
|
|
continue; |
|
|
else |
|
|
{ |
|
|
register Lisp_Object param_index, old_value; |
|
|
|
|
|
old_value = get_frame_param (f, prop); |
|
|
|
|
|
store_frame_param (f, prop, val); |
|
|
|
|
|
param_index = Fget (prop, Qx_frame_parameter); |
|
|
if (NATNUMP (param_index) |
|
|
&& (XFASTINT (param_index) |
|
|
< sizeof (x_frame_parms)/sizeof (x_frame_parms[0]))) |
|
|
(*x_frame_parms[XINT (param_index)].setter)(f, val, old_value); |
|
|
} |
|
|
} |
|
|
|
|
|
/* Don't die if just one of these was set. */ |
|
|
if (EQ (left, Qunbound)) |
|
|
{ |
|
|
left_no_change = 1; |
|
|
if (f->output_data.w32->left_pos < 0) |
|
|
left = Fcons (Qplus, Fcons (make_number (f->output_data.w32->left_pos), Qnil)); |
|
|
else |
|
|
XSETINT (left, f->output_data.w32->left_pos); |
|
|
} |
|
|
if (EQ (top, Qunbound)) |
|
|
{ |
|
|
top_no_change = 1; |
|
|
if (f->output_data.w32->top_pos < 0) |
|
|
top = Fcons (Qplus, Fcons (make_number (f->output_data.w32->top_pos), Qnil)); |
|
|
else |
|
|
XSETINT (top, f->output_data.w32->top_pos); |
|
|
} |
|
|
|
|
|
/* If one of the icon positions was not set, preserve or default it. */ |
|
|
if (EQ (icon_left, Qunbound) || ! INTEGERP (icon_left)) |
|
|
{ |
|
|
icon_left_no_change = 1; |
|
|
icon_left = Fcdr (Fassq (Qicon_left, f->param_alist)); |
|
|
if (NILP (icon_left)) |
|
|
XSETINT (icon_left, 0); |
|
|
} |
|
|
if (EQ (icon_top, Qunbound) || ! INTEGERP (icon_top)) |
|
|
{ |
|
|
icon_top_no_change = 1; |
|
|
icon_top = Fcdr (Fassq (Qicon_top, f->param_alist)); |
|
|
if (NILP (icon_top)) |
|
|
XSETINT (icon_top, 0); |
|
|
} |
|
|
|
|
|
if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set) |
|
|
{ |
|
|
/* If the frame is visible already and the fullscreen parameter is |
|
|
being set, it is too late to set WM manager hints to specify |
|
|
size and position. |
|
|
Here we first get the width, height and position that applies to |
|
|
fullscreen. We then move the frame to the appropriate |
|
|
position. Resize of the frame is taken care of in the code after |
|
|
this if-statement. */ |
|
|
int new_left, new_top; |
|
|
|
|
|
x_fullscreen_adjust (f, &width, &height, &new_top, &new_left); |
|
|
x_fullscreen_move (f, new_top, new_left); |
|
|
} |
|
|
|
|
|
/* Don't set these parameters unless they've been explicitly |
|
|
specified. The window might be mapped or resized while we're in |
|
|
this function, and we don't want to override that unless the lisp |
|
|
code has asked for it. |
|
|
|
|
|
Don't set these parameters unless they actually differ from the |
|
|
window's current parameters; the window may not actually exist |
|
|
yet. */ |
|
|
{ |
|
|
Lisp_Object frame; |
|
|
|
|
|
check_frame_size (f, &height, &width); |
|
|
|
|
|
XSETFRAME (frame, f); |
|
|
|
|
|
if (width != FRAME_WIDTH (f) |
|
|
|| height != FRAME_HEIGHT (f) |
|
|
|| FRAME_NEW_HEIGHT (f) || FRAME_NEW_WIDTH (f)) |
|
|
Fset_frame_size (frame, make_number (width), make_number (height)); |
|
|
|
|
|
if ((!NILP (left) || !NILP (top)) |
|
|
&& ! (left_no_change && top_no_change) |
|
|
&& ! (NUMBERP (left) && XINT (left) == f->output_data.w32->left_pos |
|
|
&& NUMBERP (top) && XINT (top) == f->output_data.w32->top_pos)) |
|
|
{ |
|
|
int leftpos = 0; |
|
|
int toppos = 0; |
|
|
|
|
|
/* Record the signs. */ |
|
|
f->output_data.w32->size_hint_flags &= ~ (XNegative | YNegative); |
|
|
if (EQ (left, Qminus)) |
|
|
f->output_data.w32->size_hint_flags |= XNegative; |
|
|
else if (INTEGERP (left)) |
|
|
{ |
|
|
leftpos = XINT (left); |
|
|
if (leftpos < 0) |
|
|
f->output_data.w32->size_hint_flags |= XNegative; |
|
|
} |
|
|
else if (CONSP (left) && EQ (XCAR (left), Qminus) |
|
|
&& CONSP (XCDR (left)) |
|
|
&& INTEGERP (XCAR (XCDR (left)))) |
|
|
{ |
|
|
leftpos = - XINT (XCAR (XCDR (left))); |
|
|
f->output_data.w32->size_hint_flags |= XNegative; |
|
|
} |
|
|
else if (CONSP (left) && EQ (XCAR (left), Qplus) |
|
|
&& CONSP (XCDR (left)) |
|
|
&& INTEGERP (XCAR (XCDR (left)))) |
|
|
{ |
|
|
leftpos = XINT (XCAR (XCDR (left))); |
|
|
} |
|
|
|
|
|
if (EQ (top, Qminus)) |
|
|
f->output_data.w32->size_hint_flags |= YNegative; |
|
|
else if (INTEGERP (top)) |
|
|
{ |
|
|
toppos = XINT (top); |
|
|
if (toppos < 0) |
|
|
f->output_data.w32->size_hint_flags |= YNegative; |
|
|
} |
|
|
else if (CONSP (top) && EQ (XCAR (top), Qminus) |
|
|
&& CONSP (XCDR (top)) |
|
|
&& INTEGERP (XCAR (XCDR (top)))) |
|
|
{ |
|
|
toppos = - XINT (XCAR (XCDR (top))); |
|
|
f->output_data.w32->size_hint_flags |= YNegative; |
|
|
} |
|
|
else if (CONSP (top) && EQ (XCAR (top), Qplus) |
|
|
&& CONSP (XCDR (top)) |
|
|
&& INTEGERP (XCAR (XCDR (top)))) |
|
|
{ |
|
|
toppos = XINT (XCAR (XCDR (top))); |
|
|
} |
|
|
|
|
|
|
|
|
/* Store the numeric value of the position. */ |
|
|
f->output_data.w32->top_pos = toppos; |
|
|
f->output_data.w32->left_pos = leftpos; |
|
|
|
|
|
f->output_data.w32->win_gravity = NorthWestGravity; |
|
|
|
|
|
/* Actually set that position, and convert to absolute. */ |
|
|
x_set_offset (f, leftpos, toppos, -1); |
|
|
} |
|
|
|
|
|
if ((!NILP (icon_left) || !NILP (icon_top)) |
|
|
&& ! (icon_left_no_change && icon_top_no_change)) |
|
|
x_wm_set_icon_position (f, XINT (icon_left), XINT (icon_top)); |
|
|
} |
|
|
|
|
|
UNGCPRO; |
|
|
} |
|
636 |
|
|
637 |
/* Store the screen positions of frame F into XPTR and YPTR. |
/* Store the screen positions of frame F into XPTR and YPTR. |
638 |
These are the positions of the containing window manager window, |
These are the positions of the containing window manager window, |
662 |
*yptr = pt.y; |
*yptr = pt.y; |
663 |
} |
} |
664 |
|
|
|
/* Insert a description of internally-recorded parameters of frame X |
|
|
into the parameter alist *ALISTPTR that is to be given to the user. |
|
|
Only parameters that are specific to W32 |
|
|
and whose values are not correctly recorded in the frame's |
|
|
param_alist need to be considered here. */ |
|
|
|
|
|
void |
|
|
x_report_frame_params (f, alistptr) |
|
|
struct frame *f; |
|
|
Lisp_Object *alistptr; |
|
|
{ |
|
|
char buf[16]; |
|
|
Lisp_Object tem; |
|
|
|
|
|
/* Represent negative positions (off the top or left screen edge) |
|
|
in a way that Fmodify_frame_parameters will understand correctly. */ |
|
|
XSETINT (tem, f->output_data.w32->left_pos); |
|
|
if (f->output_data.w32->left_pos >= 0) |
|
|
store_in_alist (alistptr, Qleft, tem); |
|
|
else |
|
|
store_in_alist (alistptr, Qleft, Fcons (Qplus, Fcons (tem, Qnil))); |
|
|
|
|
|
XSETINT (tem, f->output_data.w32->top_pos); |
|
|
if (f->output_data.w32->top_pos >= 0) |
|
|
store_in_alist (alistptr, Qtop, tem); |
|
|
else |
|
|
store_in_alist (alistptr, Qtop, Fcons (Qplus, Fcons (tem, Qnil))); |
|
|
|
|
|
store_in_alist (alistptr, Qborder_width, |
|
|
make_number (f->output_data.w32->border_width)); |
|
|
store_in_alist (alistptr, Qinternal_border_width, |
|
|
make_number (f->output_data.w32->internal_border_width)); |
|
|
store_in_alist (alistptr, Qleft_fringe, |
|
|
make_number (f->output_data.w32->left_fringe_width)); |
|
|
store_in_alist (alistptr, Qright_fringe, |
|
|
make_number (f->output_data.w32->right_fringe_width)); |
|
|
store_in_alist (alistptr, Qscroll_bar_width, |
|
|
make_number (FRAME_HAS_VERTICAL_SCROLL_BARS (f) |
|
|
? FRAME_SCROLL_BAR_PIXEL_WIDTH(f) |
|
|
: 0)); |
|
|
sprintf (buf, "%ld", (long) FRAME_W32_WINDOW (f)); |
|
|
store_in_alist (alistptr, Qwindow_id, |
|
|
build_string (buf)); |
|
|
store_in_alist (alistptr, Qicon_name, f->icon_name); |
|
|
FRAME_SAMPLE_VISIBILITY (f); |
|
|
store_in_alist (alistptr, Qvisibility, |
|
|
(FRAME_VISIBLE_P (f) ? Qt |
|
|
: FRAME_ICONIFIED_P (f) ? Qicon : Qnil)); |
|
|
store_in_alist (alistptr, Qdisplay, |
|
|
XCAR (FRAME_W32_DISPLAY_INFO (f)->name_list_element)); |
|
|
} |
|
665 |
|
|
666 |
|
|
667 |
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, |
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, |
722 |
CHECK_STRING (filename); |
CHECK_STRING (filename); |
723 |
abspath = Fexpand_file_name (filename, Qnil); |
abspath = Fexpand_file_name (filename, Qnil); |
724 |
|
|
725 |
fp = fopen (XSTRING (filename)->data, "rt"); |
fp = fopen (SDATA (filename), "rt"); |
726 |
if (fp) |
if (fp) |
727 |
{ |
{ |
728 |
char buf[512]; |
char buf[512]; |
752 |
} |
} |
753 |
|
|
754 |
/* The default colors for the w32 color map */ |
/* The default colors for the w32 color map */ |
755 |
typedef struct colormap_t |
typedef struct colormap_t |
756 |
{ |
{ |
757 |
char *name; |
char *name; |
758 |
COLORREF colorref; |
COLORREF colorref; |
759 |
} colormap_t; |
} colormap_t; |
760 |
|
|
761 |
colormap_t w32_color_map[] = |
colormap_t w32_color_map[] = |
762 |
{ |
{ |
763 |
{"snow" , PALETTERGB (255,250,250)}, |
{"snow" , PALETTERGB (255,250,250)}, |
764 |
{"ghost white" , PALETTERGB (248,248,255)}, |
{"ghost white" , PALETTERGB (248,248,255)}, |
1009 |
int i; |
int i; |
1010 |
colormap_t *pc = w32_color_map; |
colormap_t *pc = w32_color_map; |
1011 |
Lisp_Object cmap; |
Lisp_Object cmap; |
1012 |
|
|
1013 |
BLOCK_INPUT; |
BLOCK_INPUT; |
1014 |
|
|
1015 |
cmap = Qnil; |
cmap = Qnil; |
1016 |
|
|
1017 |
for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]); |
for (i = 0; i < sizeof (w32_color_map) / sizeof (w32_color_map[0]); |
1018 |
pc++, i++) |
pc++, i++) |
1019 |
cmap = Fcons (Fcons (build_string (pc->name), |
cmap = Fcons (Fcons (build_string (pc->name), |
1020 |
make_number (pc->colorref)), |
make_number (pc->colorref)), |
1021 |
cmap); |
cmap); |
1022 |
|
|
1023 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1024 |
|
|
1025 |
return (cmap); |
return (cmap); |
1026 |
} |
} |
1027 |
|
|
1028 |
Lisp_Object |
Lisp_Object |
1029 |
w32_to_x_color (rgb) |
w32_to_x_color (rgb) |
1030 |
Lisp_Object rgb; |
Lisp_Object rgb; |
1031 |
{ |
{ |
1032 |
Lisp_Object color; |
Lisp_Object color; |
1033 |
|
|
1034 |
CHECK_NUMBER (rgb); |
CHECK_NUMBER (rgb); |
1035 |
|
|
1036 |
BLOCK_INPUT; |
BLOCK_INPUT; |
1037 |
|
|
1038 |
color = Frassq (rgb, Vw32_color_map); |
color = Frassq (rgb, Vw32_color_map); |
1039 |
|
|
1040 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1041 |
|
|
1042 |
if (!NILP (color)) |
if (!NILP (color)) |
1043 |
return (Fcar (color)); |
return (Fcar (color)); |
1044 |
else |
else |
1062 |
|
|
1063 |
tem = Fcar (elt); |
tem = Fcar (elt); |
1064 |
|
|
1065 |
if (lstrcmpi (XSTRING (tem)->data, colorname) == 0) |
if (lstrcmpi (SDATA (tem), colorname) == 0) |
1066 |
{ |
{ |
1067 |
ret = XUINT (Fcdr (elt)); |
ret = XUINT (Fcdr (elt)); |
1068 |
break; |
break; |
1077 |
return ret; |
return ret; |
1078 |
} |
} |
1079 |
|
|
1080 |
COLORREF |
COLORREF |
1081 |
x_to_w32_color (colorname) |
x_to_w32_color (colorname) |
1082 |
char * colorname; |
char * colorname; |
1083 |
{ |
{ |
1091 |
char *color; |
char *color; |
1092 |
int size; |
int size; |
1093 |
color = colorname + 1; |
color = colorname + 1; |
1094 |
|
|
1095 |
size = strlen(color); |
size = strlen(color); |
1096 |
if (size == 3 || size == 6 || size == 9 || size == 12) |
if (size == 3 || size == 6 || size == 9 || size == 12) |
1097 |
{ |
{ |
1100 |
pos = 0; |
pos = 0; |
1101 |
size /= 3; |
size /= 3; |
1102 |
colorval = 0; |
colorval = 0; |
1103 |
|
|
1104 |
for (i = 0; i < 3; i++) |
for (i = 0; i < 3; i++) |
1105 |
{ |
{ |
1106 |
char *end; |
char *end; |
1156 |
{ |
{ |
1157 |
char *end; |
char *end; |
1158 |
unsigned long value; |
unsigned long value; |
1159 |
|
|
1160 |
/* The check for 'x' in the following conditional takes into |
/* The check for 'x' in the following conditional takes into |
1161 |
account the fact that strtol allows a "0x" in front of |
account the fact that strtol allows a "0x" in front of |
1162 |
our numbers, and we don't. */ |
our numbers, and we don't. */ |
1219 |
if (value < 0.0 || value > 1.0) |
if (value < 0.0 || value > 1.0) |
1220 |
break; |
break; |
1221 |
val = (UINT)(0x100 * value); |
val = (UINT)(0x100 * value); |
1222 |
/* We used 0x100 instead of 0xFF to give an continuous |
/* We used 0x100 instead of 0xFF to give a continuous |
1223 |
range between 0.0 and 1.0 inclusive. The next statement |
range between 0.0 and 1.0 inclusive. The next statement |
1224 |
fixes the 1.0 case. */ |
fixes the 1.0 case. */ |
1225 |
if (val == 0x100) |
if (val == 0x100) |
1243 |
RGB. */ |
RGB. */ |
1244 |
|
|
1245 |
/* If we fail to lookup the color name in w32_color_map, then check the |
/* If we fail to lookup the color name in w32_color_map, then check the |
1246 |
colorname to see if it can be crudely approximated: If the X color |
colorname to see if it can be crudely approximated: If the X color |
1247 |
ends in a number (e.g., "darkseagreen2"), strip the number and |
ends in a number (e.g., "darkseagreen2"), strip the number and |
1248 |
return the result of looking up the base color name. */ |
return the result of looking up the base color name. */ |
1249 |
ret = w32_color_map_lookup (colorname); |
ret = w32_color_map_lookup (colorname); |
1250 |
if (NILP (ret)) |
if (NILP (ret)) |
1251 |
{ |
{ |
1252 |
int len = strlen (colorname); |
int len = strlen (colorname); |
1253 |
|
|
1254 |
if (isdigit (colorname[len - 1])) |
if (isdigit (colorname[len - 1])) |
1255 |
{ |
{ |
1256 |
char *ptr, *approx = alloca (len + 1); |
char *ptr, *approx = alloca (len + 1); |
1257 |
|
|
1258 |
strcpy (approx, colorname); |
strcpy (approx, colorname); |
1259 |
ptr = &approx[len - 1]; |
ptr = &approx[len - 1]; |
1260 |
while (ptr > approx && isdigit (*ptr)) |
while (ptr > approx && isdigit (*ptr)) |
1261 |
*ptr-- = '\0'; |
*ptr-- = '\0'; |
1262 |
|
|
1263 |
ret = w32_color_map_lookup (approx); |
ret = w32_color_map_lookup (approx); |
1264 |
} |
} |
1265 |
} |
} |
1266 |
|
|
1267 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1268 |
return ret; |
return ret; |
1269 |
} |
} |
1418 |
|
|
1419 |
tem = x_to_w32_color (color); |
tem = x_to_w32_color (color); |
1420 |
|
|
1421 |
if (!NILP (tem)) |
if (!NILP (tem)) |
1422 |
{ |
{ |
1423 |
if (f) |
if (f) |
1424 |
{ |
{ |
1435 |
one_w32_display_info.color_list; |
one_w32_display_info.color_list; |
1436 |
struct w32_palette_entry ** prev = |
struct w32_palette_entry ** prev = |
1437 |
&one_w32_display_info.color_list; |
&one_w32_display_info.color_list; |
1438 |
|
|
1439 |
/* check if color is already mapped */ |
/* check if color is already mapped */ |
1440 |
while (entry) |
while (entry) |
1441 |
{ |
{ |
1465 |
w32_color_ref = XUINT (tem) | 0x2000000; |
w32_color_ref = XUINT (tem) | 0x2000000; |
1466 |
|
|
1467 |
color_def->pixel = w32_color_ref; |
color_def->pixel = w32_color_ref; |
1468 |
color_def->red = GetRValue (w32_color_ref); |
color_def->red = GetRValue (w32_color_ref) * 256; |
1469 |
color_def->green = GetGValue (w32_color_ref); |
color_def->green = GetGValue (w32_color_ref) * 256; |
1470 |
color_def->blue = GetBValue (w32_color_ref); |
color_def->blue = GetBValue (w32_color_ref) * 256; |
1471 |
|
|
1472 |
return 1; |
return 1; |
1473 |
} |
} |
1474 |
else |
else |
1475 |
{ |
{ |
1476 |
return 0; |
return 0; |
1477 |
} |
} |
1492 |
|
|
1493 |
CHECK_STRING (arg); |
CHECK_STRING (arg); |
1494 |
|
|
1495 |
if (strcmp (XSTRING (arg)->data, "black") == 0) |
if (strcmp (SDATA (arg), "black") == 0) |
1496 |
return BLACK_PIX_DEFAULT (f); |
return BLACK_PIX_DEFAULT (f); |
1497 |
else if (strcmp (XSTRING (arg)->data, "white") == 0) |
else if (strcmp (SDATA (arg), "white") == 0) |
1498 |
return WHITE_PIX_DEFAULT (f); |
return WHITE_PIX_DEFAULT (f); |
1499 |
|
|
1500 |
if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1) |
if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1) |
1502 |
|
|
1503 |
/* w32_defined_color is responsible for coping with failures |
/* w32_defined_color is responsible for coping with failures |
1504 |
by looking for a near-miss. */ |
by looking for a near-miss. */ |
1505 |
if (w32_defined_color (f, XSTRING (arg)->data, &cdef, 1)) |
if (w32_defined_color (f, SDATA (arg), &cdef, 1)) |
1506 |
return cdef.pixel; |
return cdef.pixel; |
1507 |
|
|
1508 |
/* defined_color failed; return an ultimate default. */ |
/* defined_color failed; return an ultimate default. */ |
1509 |
return def; |
return def; |
1510 |
} |
} |
1511 |
|
|
|
/* Change the `line-spacing' frame parameter of frame F. OLD_VALUE is |
|
|
the previous value of that parameter, NEW_VALUE is the new value. */ |
|
|
|
|
|
static void |
|
|
x_set_line_spacing (f, new_value, old_value) |
|
|
struct frame *f; |
|
|
Lisp_Object new_value, old_value; |
|
|
{ |
|
|
if (NILP (new_value)) |
|
|
f->extra_line_spacing = 0; |
|
|
else if (NATNUMP (new_value)) |
|
|
f->extra_line_spacing = XFASTINT (new_value); |
|
|
else |
|
|
Fsignal (Qerror, Fcons (build_string ("Invalid line-spacing"), |
|
|
Fcons (new_value, Qnil))); |
|
|
if (FRAME_VISIBLE_P (f)) |
|
|
redraw_frame (f); |
|
|
} |
|
|
|
|
|
|
|
|
/* Change the `fullscreen' frame parameter of frame F. OLD_VALUE is |
|
|
the previous value of that parameter, NEW_VALUE is the new value. */ |
|
|
|
|
|
static void |
|
|
x_set_fullscreen (f, new_value, old_value) |
|
|
struct frame *f; |
|
|
Lisp_Object new_value, old_value; |
|
|
{ |
|
|
if (NILP (new_value)) |
|
|
f->output_data.w32->want_fullscreen = FULLSCREEN_NONE; |
|
|
else if (EQ (new_value, Qfullboth)) |
|
|
f->output_data.w32->want_fullscreen = FULLSCREEN_BOTH; |
|
|
else if (EQ (new_value, Qfullwidth)) |
|
|
f->output_data.w32->want_fullscreen = FULLSCREEN_WIDTH; |
|
|
else if (EQ (new_value, Qfullheight)) |
|
|
f->output_data.w32->want_fullscreen = FULLSCREEN_HEIGHT; |
|
|
} |
|
|
|
|
|
|
|
|
/* Change the `screen-gamma' frame parameter of frame F. OLD_VALUE is |
|
|
the previous value of that parameter, NEW_VALUE is the new value. */ |
|
|
|
|
|
static void |
|
|
x_set_screen_gamma (f, new_value, old_value) |
|
|
struct frame *f; |
|
|
Lisp_Object new_value, old_value; |
|
|
{ |
|
|
if (NILP (new_value)) |
|
|
f->gamma = 0; |
|
|
else if (NUMBERP (new_value) && XFLOATINT (new_value) > 0) |
|
|
/* The value 0.4545 is the normal viewing gamma. */ |
|
|
f->gamma = 1.0 / (0.4545 * XFLOATINT (new_value)); |
|
|
else |
|
|
Fsignal (Qerror, Fcons (build_string ("Invalid screen-gamma"), |
|
|
Fcons (new_value, Qnil))); |
|
|
|
|
|
clear_face_cache (0); |
|
|
} |
|
1512 |
|
|
1513 |
|
|
1514 |
/* Functions called only from `x_set_frame_param' |
/* Functions called only from `x_set_frame_param' |
1567 |
struct frame *f; |
struct frame *f; |
1568 |
Lisp_Object arg, oldval; |
Lisp_Object arg, oldval; |
1569 |
{ |
{ |
1570 |
Cursor cursor, nontext_cursor, mode_cursor, cross_cursor; |
Cursor cursor, nontext_cursor, mode_cursor, hand_cursor; |
1571 |
int count; |
int count; |
1572 |
int mask_color; |
int mask_color; |
1573 |
|
|
1615 |
else |
else |
1616 |
hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch); |
hourglass_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_watch); |
1617 |
x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s"); |
x_check_errors (FRAME_W32_DISPLAY (f), "bad busy pointer cursor: %s"); |
1618 |
|
|
1619 |
x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s"); |
x_check_errors (FRAME_W32_DISPLAY (f), "bad nontext pointer cursor: %s"); |
1620 |
if (!EQ (Qnil, Vx_mode_pointer_shape)) |
if (!EQ (Qnil, Vx_mode_pointer_shape)) |
1621 |
{ |
{ |
1630 |
if (!EQ (Qnil, Vx_sensitive_text_pointer_shape)) |
if (!EQ (Qnil, Vx_sensitive_text_pointer_shape)) |
1631 |
{ |
{ |
1632 |
CHECK_NUMBER (Vx_sensitive_text_pointer_shape); |
CHECK_NUMBER (Vx_sensitive_text_pointer_shape); |
1633 |
cross_cursor |
hand_cursor |
1634 |
= XCreateFontCursor (FRAME_W32_DISPLAY (f), |
= XCreateFontCursor (FRAME_W32_DISPLAY (f), |
1635 |
XINT (Vx_sensitive_text_pointer_shape)); |
XINT (Vx_sensitive_text_pointer_shape)); |
1636 |
} |
} |
1637 |
else |
else |
1638 |
cross_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair); |
hand_cursor = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_crosshair); |
1639 |
|
|
1640 |
if (!NILP (Vx_window_horizontal_drag_shape)) |
if (!NILP (Vx_window_horizontal_drag_shape)) |
1641 |
{ |
{ |
1671 |
&fore_color, &back_color); |
&fore_color, &back_color); |
1672 |
XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor, |
XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor, |
1673 |
&fore_color, &back_color); |
&fore_color, &back_color); |
1674 |
XRecolorCursor (FRAME_W32_DISPLAY (f), cross_cursor, |
XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor, |
1675 |
&fore_color, &back_color); |
&fore_color, &back_color); |
1676 |
XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor, |
XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor, |
1677 |
&fore_color, &back_color); |
&fore_color, &back_color); |
1698 |
&& f->output_data.w32->modeline_cursor != 0) |
&& f->output_data.w32->modeline_cursor != 0) |
1699 |
XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor); |
XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->modeline_cursor); |
1700 |
f->output_data.w32->modeline_cursor = mode_cursor; |
f->output_data.w32->modeline_cursor = mode_cursor; |
1701 |
|
|
1702 |
if (cross_cursor != f->output_data.w32->cross_cursor |
if (hand_cursor != f->output_data.w32->hand_cursor |
1703 |
&& f->output_data.w32->cross_cursor != 0) |
&& f->output_data.w32->hand_cursor != 0) |
1704 |
XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->cross_cursor); |
XFreeCursor (FRAME_W32_DISPLAY (f), f->output_data.w32->hand_cursor); |
1705 |
f->output_data.w32->cross_cursor = cross_cursor; |
f->output_data.w32->hand_cursor = hand_cursor; |
1706 |
|
|
1707 |
XFlush (FRAME_W32_DISPLAY (f)); |
XFlush (FRAME_W32_DISPLAY (f)); |
1708 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1712 |
} |
} |
1713 |
|
|
1714 |
/* Defined in w32term.c. */ |
/* Defined in w32term.c. */ |
|
void x_update_cursor (struct frame *f, int on_p); |
|
|
|
|
1715 |
void |
void |
1716 |
x_set_cursor_color (f, arg, oldval) |
x_set_cursor_color (f, arg, oldval) |
1717 |
struct frame *f; |
struct frame *f; |
1726 |
fore_pixel = FRAME_BACKGROUND_PIXEL (f); |
fore_pixel = FRAME_BACKGROUND_PIXEL (f); |
1727 |
|
|
1728 |
pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); |
pixel = x_decode_color (f, arg, BLACK_PIX_DEFAULT (f)); |
1729 |
|
|
1730 |
/* Make sure that the cursor color differs from the background color. */ |
/* Make sure that the cursor color differs from the background color. */ |
1731 |
if (pixel == FRAME_BACKGROUND_PIXEL (f)) |
if (pixel == FRAME_BACKGROUND_PIXEL (f)) |
1732 |
{ |
{ |
1759 |
|
|
1760 |
/* Set the border-color of frame F to pixel value PIX. |
/* Set the border-color of frame F to pixel value PIX. |
1761 |
Note that this does not fully take effect if done before |
Note that this does not fully take effect if done before |
1762 |
F has an window. */ |
F has a window. */ |
1763 |
|
|
1764 |
void |
void |
1765 |
x_set_border_pixel (f, pix) |
x_set_border_pixel (f, pix) |
1766 |
struct frame *f; |
struct frame *f; |
1767 |
int pix; |
int pix; |
1768 |
{ |
{ |
1769 |
|
|
1770 |
f->output_data.w32->border_pixel = pix; |
f->output_data.w32->border_pixel = pix; |
1771 |
|
|
1772 |
if (FRAME_W32_WINDOW (f) != 0 && f->output_data.w32->border_width > 0) |
if (FRAME_W32_WINDOW (f) != 0 && f->output_data.w32->border_width > 0) |
1795 |
update_face_from_frame_parameter (f, Qborder_color, arg); |
update_face_from_frame_parameter (f, Qborder_color, arg); |
1796 |
} |
} |
1797 |
|
|
|
/* Value is the internal representation of the specified cursor type |
|
|
ARG. If type is BAR_CURSOR, return in *WIDTH the specified width |
|
|
of the bar cursor. */ |
|
|
|
|
|
enum text_cursor_kinds |
|
|
x_specified_cursor_type (arg, width) |
|
|
Lisp_Object arg; |
|
|
int *width; |
|
|
{ |
|
|
enum text_cursor_kinds type; |
|
|
|
|
|
if (EQ (arg, Qbar)) |
|
|
{ |
|
|
type = BAR_CURSOR; |
|
|
*width = 2; |
|
|
} |
|
|
else if (CONSP (arg) |
|
|
&& EQ (XCAR (arg), Qbar) |
|
|
&& INTEGERP (XCDR (arg)) |
|
|
&& XINT (XCDR (arg)) >= 0) |
|
|
{ |
|
|
type = BAR_CURSOR; |
|
|
*width = XINT (XCDR (arg)); |
|
|
} |
|
|
else if (EQ (arg, Qhbar)) |
|
|
{ |
|
|
type = HBAR_CURSOR; |
|
|
*width = 2; |
|
|
} |
|
|
else if (CONSP (arg) |
|
|
&& EQ (XCAR (arg), Qhbar) |
|
|
&& INTEGERP (XCDR (arg)) |
|
|
&& XINT (XCDR (arg)) >= 0) |
|
|
{ |
|
|
type = HBAR_CURSOR; |
|
|
*width = XINT (XCDR (arg)); |
|
|
} |
|
|
else if (NILP (arg)) |
|
|
type = NO_CURSOR; |
|
|
else |
|
|
/* Treat anything unknown as "box cursor". |
|
|
It was bad to signal an error; people have trouble fixing |
|
|
.Xdefaults with Emacs, when it has something bad in it. */ |
|
|
type = FILLED_BOX_CURSOR; |
|
|
|
|
|
return type; |
|
|
} |
|
1798 |
|
|
1799 |
void |
void |
1800 |
x_set_cursor_type (f, arg, oldval) |
x_set_cursor_type (f, arg, oldval) |
1801 |
FRAME_PTR f; |
FRAME_PTR f; |
1802 |
Lisp_Object arg, oldval; |
Lisp_Object arg, oldval; |
1803 |
{ |
{ |
1804 |
int width; |
set_frame_cursor_types (f, arg); |
1805 |
|
|
1806 |
FRAME_DESIRED_CURSOR (f) = x_specified_cursor_type (arg, &width); |
/* Make sure the cursor gets redrawn. */ |
1807 |
f->output_data.w32->cursor_width = width; |
cursor_type_changed = 1; |
|
|
|
|
/* Make sure the cursor gets redrawn. This is overkill, but how |
|
|
often do people change cursor types? */ |
|
|
update_mode_lines++; |
|
1808 |
} |
} |
1809 |
|
|
1810 |
void |
void |
1817 |
if (NILP (arg) && NILP (oldval)) |
if (NILP (arg) && NILP (oldval)) |
1818 |
return; |
return; |
1819 |
|
|
1820 |
if (STRINGP (arg) && STRINGP (oldval) |
if (STRINGP (arg) && STRINGP (oldval) |
1821 |
&& EQ (Fstring_equal (oldval, arg), Qt)) |
&& EQ (Fstring_equal (oldval, arg), Qt)) |
1822 |
return; |
return; |
1823 |
|
|
1836 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
1837 |
} |
} |
1838 |
|
|
|
/* Return non-nil if frame F wants a bitmap icon. */ |
|
|
|
|
|
Lisp_Object |
|
|
x_icon_type (f) |
|
|
FRAME_PTR f; |
|
|
{ |
|
|
Lisp_Object tem; |
|
|
|
|
|
tem = assq_no_quit (Qicon_type, f->param_alist); |
|
|
if (CONSP (tem)) |
|
|
return XCDR (tem); |
|
|
else |
|
|
return Qnil; |
|
|
} |
|
|
|
|
1839 |
void |
void |
1840 |
x_set_icon_name (f, arg, oldval) |
x_set_icon_name (f, arg, oldval) |
1841 |
struct frame *f; |
struct frame *f; |
1858 |
BLOCK_INPUT; |
BLOCK_INPUT; |
1859 |
|
|
1860 |
result = x_text_icon (f, |
result = x_text_icon (f, |
1861 |
(char *) XSTRING ((!NILP (f->icon_name) |
(char *) SDATA ((!NILP (f->icon_name) |
1862 |
? f->icon_name |
? f->icon_name |
1863 |
: !NILP (f->title) |
: !NILP (f->title) |
1864 |
? f->title |
? f->title |
1865 |
: f->name))->data); |
: f->name))); |
1866 |
|
|
1867 |
if (result) |
if (result) |
1868 |
{ |
{ |
1885 |
#endif |
#endif |
1886 |
} |
} |
1887 |
|
|
|
extern Lisp_Object x_new_font (); |
|
|
extern Lisp_Object x_new_fontset(); |
|
|
|
|
|
void |
|
|
x_set_font (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
Lisp_Object result; |
|
|
Lisp_Object fontset_name; |
|
|
Lisp_Object frame; |
|
|
int old_fontset = FRAME_FONTSET(f); |
|
|
|
|
|
CHECK_STRING (arg); |
|
|
|
|
|
fontset_name = Fquery_fontset (arg, Qnil); |
|
|
|
|
|
BLOCK_INPUT; |
|
|
result = (STRINGP (fontset_name) |
|
|
? x_new_fontset (f, XSTRING (fontset_name)->data) |
|
|
: x_new_font (f, XSTRING (arg)->data)); |
|
|
UNBLOCK_INPUT; |
|
|
|
|
|
if (EQ (result, Qnil)) |
|
|
error ("Font `%s' is not defined", XSTRING (arg)->data); |
|
|
else if (EQ (result, Qt)) |
|
|
error ("The characters of the given font have varying widths"); |
|
|
else if (STRINGP (result)) |
|
|
{ |
|
|
if (STRINGP (fontset_name)) |
|
|
{ |
|
|
/* Fontset names are built from ASCII font names, so the |
|
|
names may be equal despite there was a change. */ |
|
|
if (old_fontset == FRAME_FONTSET (f)) |
|
|
return; |
|
|
} |
|
|
else if (!NILP (Fequal (result, oldval))) |
|
|
return; |
|
|
|
|
|
store_frame_param (f, Qfont, result); |
|
|
recompute_basic_faces (f); |
|
|
} |
|
|
else |
|
|
abort (); |
|
|
|
|
|
do_pending_window_change (0); |
|
|
|
|
|
/* Don't call `face-set-after-frame-default' when faces haven't been |
|
|
initialized yet. This is the case when called from |
|
|
Fx_create_frame. In that case, the X widget or window doesn't |
|
|
exist either, and we can end up in x_report_frame_params with a |
|
|
null widget which gives a segfault. */ |
|
|
if (FRAME_FACE_CACHE (f)) |
|
|
{ |
|
|
XSETFRAME (frame, f); |
|
|
call1 (Qface_set_after_frame_default, frame); |
|
|
} |
|
|
} |
|
|
|
|
|
static void |
|
|
x_set_fringe_width (f, new_value, old_value) |
|
|
struct frame *f; |
|
|
Lisp_Object new_value, old_value; |
|
|
{ |
|
|
x_compute_fringe_widths (f, 1); |
|
|
} |
|
|
|
|
|
void |
|
|
x_set_border_width (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
CHECK_NUMBER (arg); |
|
|
|
|
|
if (XINT (arg) == f->output_data.w32->border_width) |
|
|
return; |
|
|
|
|
|
if (FRAME_W32_WINDOW (f) != 0) |
|
|
error ("Cannot change the border width of a window"); |
|
|
|
|
|
f->output_data.w32->border_width = XINT (arg); |
|
|
} |
|
|
|
|
|
void |
|
|
x_set_internal_border_width (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
int old = f->output_data.w32->internal_border_width; |
|
|
|
|
|
CHECK_NUMBER (arg); |
|
|
f->output_data.w32->internal_border_width = XINT (arg); |
|
|
if (f->output_data.w32->internal_border_width < 0) |
|
|
f->output_data.w32->internal_border_width = 0; |
|
|
|
|
|
if (f->output_data.w32->internal_border_width == old) |
|
|
return; |
|
|
|
|
|
if (FRAME_W32_WINDOW (f) != 0) |
|
|
{ |
|
|
x_set_window_size (f, 0, f->width, f->height); |
|
|
SET_FRAME_GARBAGED (f); |
|
|
do_pending_window_change (0); |
|
|
} |
|
|
else |
|
|
SET_FRAME_GARBAGED (f); |
|
|
} |
|
|
|
|
|
void |
|
|
x_set_visibility (f, value, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object value, oldval; |
|
|
{ |
|
|
Lisp_Object frame; |
|
|
XSETFRAME (frame, f); |
|
|
|
|
|
if (NILP (value)) |
|
|
Fmake_frame_invisible (frame, Qt); |
|
|
else if (EQ (value, Qicon)) |
|
|
Ficonify_frame (frame); |
|
|
else |
|
|
Fmake_frame_visible (frame); |
|
|
} |
|
|
|
|
1888 |
|
|
|
/* Change window heights in windows rooted in WINDOW by N lines. */ |
|
|
|
|
|
static void |
|
|
x_change_window_heights (window, n) |
|
|
Lisp_Object window; |
|
|
int n; |
|
|
{ |
|
|
struct window *w = XWINDOW (window); |
|
|
|
|
|
XSETFASTINT (w->top, XFASTINT (w->top) + n); |
|
|
XSETFASTINT (w->height, XFASTINT (w->height) - n); |
|
|
|
|
|
if (INTEGERP (w->orig_top)) |
|
|
XSETFASTINT (w->orig_top, XFASTINT (w->orig_top) + n); |
|
|
if (INTEGERP (w->orig_height)) |
|
|
XSETFASTINT (w->orig_height, XFASTINT (w->orig_height) - n); |
|
|
|
|
|
/* Handle just the top child in a vertical split. */ |
|
|
if (!NILP (w->vchild)) |
|
|
x_change_window_heights (w->vchild, n); |
|
|
|
|
|
/* Adjust all children in a horizontal split. */ |
|
|
for (window = w->hchild; !NILP (window); window = w->next) |
|
|
{ |
|
|
w = XWINDOW (window); |
|
|
x_change_window_heights (window, n); |
|
|
} |
|
|
} |
|
|
|
|
1889 |
void |
void |
1890 |
x_set_menu_bar_lines (f, value, oldval) |
x_set_menu_bar_lines (f, value, oldval) |
1891 |
struct frame *f; |
struct frame *f; |
1964 |
} |
} |
1965 |
|
|
1966 |
FRAME_TOOL_BAR_LINES (f) = nlines; |
FRAME_TOOL_BAR_LINES (f) = nlines; |
1967 |
x_change_window_heights (root_window, delta); |
change_window_heights (root_window, delta); |
1968 |
adjust_glyphs (f); |
adjust_glyphs (f); |
1969 |
|
|
1970 |
/* We also have to make sure that the internal border at the top of |
/* We also have to make sure that the internal border at the top of |
2021 |
Lisp_Object name; |
Lisp_Object name; |
2022 |
int explicit; |
int explicit; |
2023 |
{ |
{ |
2024 |
/* Make sure that requests from lisp code override requests from |
/* Make sure that requests from lisp code override requests from |
2025 |
Emacs redisplay code. */ |
Emacs redisplay code. */ |
2026 |
if (explicit) |
if (explicit) |
2027 |
{ |
{ |
2041 |
/* Check for no change needed in this very common case |
/* Check for no change needed in this very common case |
2042 |
before we do any consing. */ |
before we do any consing. */ |
2043 |
if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name, |
if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name, |
2044 |
XSTRING (f->name)->data)) |
SDATA (f->name))) |
2045 |
return; |
return; |
2046 |
name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name); |
name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name); |
2047 |
} |
} |
2065 |
name = ENCODE_SYSTEM (name); |
name = ENCODE_SYSTEM (name); |
2066 |
|
|
2067 |
BLOCK_INPUT; |
BLOCK_INPUT; |
2068 |
SetWindowText(FRAME_W32_WINDOW (f), XSTRING (name)->data); |
SetWindowText(FRAME_W32_WINDOW (f), SDATA (name)); |
2069 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
2070 |
} |
} |
2071 |
} |
} |
2125 |
name = ENCODE_SYSTEM (name); |
name = ENCODE_SYSTEM (name); |
2126 |
|
|
2127 |
BLOCK_INPUT; |
BLOCK_INPUT; |
2128 |
SetWindowText(FRAME_W32_WINDOW (f), XSTRING (name)->data); |
SetWindowText(FRAME_W32_WINDOW (f), SDATA (name)); |
2129 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
2130 |
} |
} |
2131 |
} |
} |
|
|
|
|
void |
|
|
x_set_autoraise (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
f->auto_raise = !EQ (Qnil, arg); |
|
|
} |
|
|
|
|
|
void |
|
|
x_set_autolower (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
f->auto_lower = !EQ (Qnil, arg); |
|
|
} |
|
|
|
|
|
void |
|
|
x_set_unsplittable (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
f->no_split = !NILP (arg); |
|
|
} |
|
2132 |
|
|
|
void |
|
|
x_set_vertical_scroll_bars (f, arg, oldval) |
|
|
struct frame *f; |
|
|
Lisp_Object arg, oldval; |
|
|
{ |
|
|
if ((EQ (arg, Qleft) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) |
|
|
|| (EQ (arg, Qright) && FRAME_HAS_VERTICAL_SCROLL_BARS_ON_LEFT (f)) |
|
|
|| (NILP (arg) && FRAME_HAS_VERTICAL_SCROLL_BARS (f)) |
|
|
|| (!NILP (arg) && ! FRAME_HAS_VERTICAL_SCROLL_BARS (f))) |
|
|
{ |
|
|
FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = NILP (arg) ? |
|
|
vertical_scroll_bar_none : |
|
|
/* Put scroll bars on the right by default, as is conventional |
|
|
on MS-Windows. */ |
|
|
EQ (Qleft, arg) |
|
|
? vertical_scroll_bar_left |
|
|
: vertical_scroll_bar_right; |
|
|
|
|
|
/* We set this parameter before creating the window for the |
|
|
frame, so we can get the geometry right from the start. |
|
|
However, if the window hasn't been created yet, we shouldn't |
|
|
call x_set_window_size. */ |
|
|
if (FRAME_W32_WINDOW (f)) |
|
|
x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f)); |
|
|
do_pending_window_change (0); |
|
|
} |
|
|
} |
|
2133 |
|
|
2134 |
void |
void x_set_scroll_bar_default_width (f) |
|
x_set_scroll_bar_width (f, arg, oldval) |
|
2135 |
struct frame *f; |
struct frame *f; |
|
Lisp_Object arg, oldval; |
|
2136 |
{ |
{ |
2137 |
int wid = FONT_WIDTH (f->output_data.w32->font); |
int wid = FONT_WIDTH (f->output_data.w32->font); |
2138 |
|
|
2139 |
if (NILP (arg)) |
FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); |
2140 |
{ |
FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) + |
2141 |
FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL); |
wid - 1) / wid; |
|
FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) + |
|
|
wid - 1) / wid; |
|
|
if (FRAME_W32_WINDOW (f)) |
|
|
x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f)); |
|
|
do_pending_window_change (0); |
|
|
} |
|
|
else if (INTEGERP (arg) && XINT (arg) > 0 |
|
|
&& XFASTINT (arg) != FRAME_SCROLL_BAR_PIXEL_WIDTH (f)) |
|
|
{ |
|
|
FRAME_SCROLL_BAR_PIXEL_WIDTH (f) = XFASTINT (arg); |
|
|
FRAME_SCROLL_BAR_COLS (f) = (FRAME_SCROLL_BAR_PIXEL_WIDTH (f) |
|
|
+ wid-1) / wid; |
|
|
if (FRAME_W32_WINDOW (f)) |
|
|
x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f)); |
|
|
do_pending_window_change (0); |
|
|
} |
|
|
change_frame_size (f, 0, FRAME_WIDTH (f), 0, 0, 0); |
|
|
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.hpos = 0; |
|
|
XWINDOW (FRAME_SELECTED_WINDOW (f))->cursor.x = 0; |
|
|
} |
|
|
|
|
|
/* Subroutines of creating an frame. */ |
|
|
|
|
|
/* Make sure that Vx_resource_name is set to a reasonable value. |
|
|
Fix it up, or set it to `emacs' if it is too hopeless. */ |
|
|
|
|
|
static void |
|
|
validate_x_resource_name () |
|
|
{ |
|
|
int len = 0; |
|
|
/* Number of valid characters in the resource name. */ |
|
|
int good_count = 0; |
|
|
/* Number of invalid characters in the resource name. */ |
|
|
int bad_count = 0; |
|
|
Lisp_Object new; |
|
|
int i; |
|
|
|
|
|
if (STRINGP (Vx_resource_name)) |
|
|
{ |
|
|
unsigned char *p = XSTRING (Vx_resource_name)->data; |
|
|
int i; |
|
|
|
|
|
len = STRING_BYTES (XSTRING (Vx_resource_name)); |
|
|
|
|
|
/* Only letters, digits, - and _ are valid in resource names. |
|
|
Count the valid characters and count the invalid ones. */ |
|
|
for (i = 0; i < len; i++) |
|
|
{ |
|
|
int c = p[i]; |
|
|
if (! ((c >= 'a' && c <= 'z') |
|
|
|| (c >= 'A' && c <= 'Z') |
|
|
|| (c >= '0' && c <= '9') |
|
|
|| c == '-' || c == '_')) |
|
|
bad_count++; |
|
|
else |
|
|
good_count++; |
|
|
} |
|
|
} |
|
|
else |
|
|
/* Not a string => completely invalid. */ |
|
|
bad_count = 5, good_count = 0; |
|
|
|
|
|
/* If name is valid already, return. */ |
|
|
if (bad_count == 0) |
|
|
return; |
|
|
|
|
|
/* If name is entirely invalid, or nearly so, use `emacs'. */ |
|
|
if (good_count == 0 |
|
|
|| (good_count == 1 && bad_count > 0)) |
|
|
{ |
|
|
Vx_resource_name = build_string ("emacs"); |
|
|
return; |
|
|
} |
|
|
|
|
|
/* Name is partly valid. Copy it and replace the invalid characters |
|
|
with underscores. */ |
|
|
|
|
|
Vx_resource_name = new = Fcopy_sequence (Vx_resource_name); |
|
|
|
|
|
for (i = 0; i < len; i++) |
|
|
{ |
|
|
int c = XSTRING (new)->data[i]; |
|
|
if (! ((c >= 'a' && c <= 'z') |
|
|
|| (c >= 'A' && c <= 'Z') |
|
|
|| (c >= '0' && c <= '9') |
|
|
|| c == '-' || c == '_')) |
|
|
XSTRING (new)->data[i] = '_'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
extern char *x_get_string_resource (); |
|
|
|
|
|
DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0, |
|
|
doc: /* Return the value of ATTRIBUTE, of class CLASS, from the X defaults database. |
|
|
This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the |
|
|
class, where INSTANCE is the name under which Emacs was invoked, or |
|
|
the name specified by the `-name' or `-rn' command-line arguments. |
|
|
|
|
|
The optional arguments COMPONENT and SUBCLASS add to the key and the |
|
|
class, respectively. You must specify both of them or neither. |
|
|
If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE' |
|
|
and the class is `Emacs.CLASS.SUBCLASS'. */) |
|
|
(attribute, class, component, subclass) |
|
|
Lisp_Object attribute, class, component, subclass; |
|
|
{ |
|
|
register char *value; |
|
|
char *name_key; |
|
|
char *class_key; |
|
|
|
|
|
CHECK_STRING (attribute); |
|
|
CHECK_STRING (class); |
|
|
|
|
|
if (!NILP (component)) |
|
|
CHECK_STRING (component); |
|
|
if (!NILP (subclass)) |
|
|
CHECK_STRING (subclass); |
|
|
if (NILP (component) != NILP (subclass)) |
|
|
error ("x-get-resource: must specify both COMPONENT and SUBCLASS or neither"); |
|
|
|
|
|
validate_x_resource_name (); |
|
|
|
|
|
/* Allocate space for the components, the dots which separate them, |
|
|
and the final '\0'. Make them big enough for the worst case. */ |
|
|
name_key = (char *) alloca (STRING_BYTES (XSTRING (Vx_resource_name)) |
|
|
+ (STRINGP (component) |
|
|
? STRING_BYTES (XSTRING (component)) : 0) |
|
|
+ STRING_BYTES (XSTRING (attribute)) |
|
|
+ 3); |
|
|
|
|
|
class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) |
|
|
+ STRING_BYTES (XSTRING (class)) |
|
|
+ (STRINGP (subclass) |
|
|
? STRING_BYTES (XSTRING (subclass)) : 0) |
|
|
+ 3); |
|
|
|
|
|
/* Start with emacs.FRAMENAME for the name (the specific one) |
|
|
and with `Emacs' for the class key (the general one). */ |
|
|
strcpy (name_key, XSTRING (Vx_resource_name)->data); |
|
|
strcpy (class_key, EMACS_CLASS); |
|
|
|
|
|
strcat (class_key, "."); |
|
|
strcat (class_key, XSTRING (class)->data); |
|
|
|
|
|
if (!NILP (component)) |
|
|
{ |
|
|
strcat (class_key, "."); |
|
|
strcat (class_key, XSTRING (subclass)->data); |
|
|
|
|
|
strcat (name_key, "."); |
|
|
strcat (name_key, XSTRING (component)->data); |
|
|
} |
|
|
|
|
|
strcat (name_key, "."); |
|
|
strcat (name_key, XSTRING (attribute)->data); |
|
|
|
|
|
value = x_get_string_resource (Qnil, |
|
|
name_key, class_key); |
|
|
|
|
|
if (value != (char *) 0) |
|
|
return build_string (value); |
|
|
else |
|
|
return Qnil; |
|
2142 |
} |
} |
2143 |
|
|
2144 |
/* Used when C code wants a resource value. */ |
|
2145 |
|
/* Subroutines of creating a frame. */ |
2146 |
|
|
|
char * |
|
|
x_get_resource_string (attribute, class) |
|
|
char *attribute, *class; |
|
|
{ |
|
|
char *name_key; |
|
|
char *class_key; |
|
|
struct frame *sf = SELECTED_FRAME (); |
|
|
|
|
|
/* Allocate space for the components, the dots which separate them, |
|
|
and the final '\0'. */ |
|
|
name_key = (char *) alloca (STRING_BYTES (XSTRING (Vinvocation_name)) |
|
|
+ strlen (attribute) + 2); |
|
|
class_key = (char *) alloca ((sizeof (EMACS_CLASS) - 1) |
|
|
+ strlen (class) + 2); |
|
|
|
|
|
sprintf (name_key, "%s.%s", |
|
|
XSTRING (Vinvocation_name)->data, |
|
|
attribute); |
|
|
sprintf (class_key, "%s.%s", EMACS_CLASS, class); |
|
|
|
|
|
return x_get_string_resource (sf, name_key, class_key); |
|
|
} |
|
|
|
|
|
/* Types we might convert a resource string into. */ |
|
|
enum resource_types |
|
|
{ |
|
|
RES_TYPE_NUMBER, |
|
|
RES_TYPE_FLOAT, |
|
|
RES_TYPE_BOOLEAN, |
|
|
RES_TYPE_STRING, |
|
|
RES_TYPE_SYMBOL |
|
|
}; |
|
2147 |
|
|
2148 |
/* Return the value of parameter PARAM. |
/* Return the value of parameter PARAM. |
2149 |
|
|
2163 |
char *class; |
char *class; |
2164 |
enum resource_types type; |
enum resource_types type; |
2165 |
{ |
{ |
2166 |
register Lisp_Object tem; |
return x_get_arg (check_x_display_info (Qnil), |
2167 |
|
alist, param, attribute, class, type); |
|
tem = Fassq (param, alist); |
|
|
if (EQ (tem, Qnil)) |
|
|
tem = Fassq (param, Vdefault_frame_alist); |
|
|
if (EQ (tem, Qnil)) |
|
|
{ |
|
|
|
|
|
if (attribute) |
|
|
{ |
|
|
tem = Fx_get_resource (build_string (attribute), |
|
|
build_string (class), |
|
|
Qnil, Qnil); |
|
|
|
|
|
if (NILP (tem)) |
|
|
return Qunbound; |
|
|
|
|
|
switch (type) |
|
|
{ |
|
|
case RES_TYPE_NUMBER: |
|
|
return make_number (atoi (XSTRING (tem)->data)); |
|
|
|
|
|
case RES_TYPE_FLOAT: |
|
|
return make_float (atof (XSTRING (tem)->data)); |
|
|
|
|
|
case RES_TYPE_BOOLEAN: |
|
|
tem = Fdowncase (tem); |
|
|
if (!strcmp (XSTRING (tem)->data, "on") |
|
|
|| !strcmp (XSTRING (tem)->data, "true")) |
|
|
return Qt; |
|
|
else |
|
|
return Qnil; |
|
|
|
|
|
case RES_TYPE_STRING: |
|
|
return tem; |
|
|
|
|
|
case RES_TYPE_SYMBOL: |
|
|
/* As a special case, we map the values `true' and `on' |
|
|
to Qt, and `false' and `off' to Qnil. */ |
|
|
{ |
|
|
Lisp_Object lower; |
|
|
lower = Fdowncase (tem); |
|
|
if (!strcmp (XSTRING (lower)->data, "on") |
|
|
|| !strcmp (XSTRING (lower)->data, "true")) |
|
|
return Qt; |
|
|
else if (!strcmp (XSTRING (lower)->data, "off") |
|
|
|| !strcmp (XSTRING (lower)->data, "false")) |
|
|
return Qnil; |
|
|
else |
|
|
return Fintern (tem, Qnil); |
|
|
} |
|
|
|
|
|
default: |
|
|
abort (); |
|
|
} |
|
|
} |
|
|
else |
|
|
return Qunbound; |
|
|
} |
|
|
return Fcdr (tem); |
|
2168 |
} |
} |
2169 |
|
|
2170 |
/* Record in frame F the specified or default value according to ALIST |
|
2171 |
of the parameter named PROP (a Lisp symbol). |
Cursor |
2172 |
If no value is specified for PROP, look for an X default for XPROP |
w32_load_cursor (LPCTSTR name) |
|
on the frame named NAME. |
|
|
If that is not found either, use the value DEFLT. */ |
|
|
|
|
|
static Lisp_Object |
|
|
x_default_parameter (f, alist, prop, deflt, xprop, xclass, type) |
|
|
struct frame *f; |
|
|
Lisp_Object alist; |
|
|
Lisp_Object prop; |
|
|
Lisp_Object deflt; |
|
|
char *xprop; |
|
|
char *xclass; |
|
|
enum resource_types type; |
|
|
{ |
|
|
Lisp_Object tem; |
|
|
|
|
|
tem = w32_get_arg (alist, prop, xprop, xclass, type); |
|
|
if (EQ (tem, Qunbound)) |
|
|
tem = deflt; |
|
|
x_set_frame_parameters (f, Fcons (Fcons (prop, tem), Qnil)); |
|
|
return tem; |
|
|
} |
|
|
|
|
|
DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0, |
|
|
doc: /* Parse an X-style geometry string STRING. |
|
|
Returns an alist of the form ((top . TOP), (left . LEFT) ... ). |
|
|
The properties returned may include `top', `left', `height', and `width'. |
|
|
The value of `left' or `top' may be an integer, |
|
|
or a list (+ N) meaning N pixels relative to top/left corner, |
|
|
or a list (- N) meaning -N pixels relative to bottom/right corner. */) |
|
|
(string) |
|
|
Lisp_Object string; |
|
|
{ |
|
|
int geometry, x, y; |
|
|
unsigned int width, height; |
|
|
Lisp_Object result; |
|
|
|
|
|
CHECK_STRING (string); |
|
|
|
|
|
geometry = XParseGeometry ((char *) XSTRING (string)->data, |
|
|
&x, &y, &width, &height); |
|
|
|
|
|
result = Qnil; |
|
|
if (geometry & XValue) |
|
|
{ |
|
|
Lisp_Object element; |
|
|
|
|
|
if (x >= 0 && (geometry & XNegative)) |
|
|
element = Fcons (Qleft, Fcons (Qminus, Fcons (make_number (-x), Qnil))); |
|
|
else if (x < 0 && ! (geometry & XNegative)) |
|
|
element = Fcons (Qleft, Fcons (Qplus, Fcons (make_number (x), Qnil))); |
|
|
else |
|
|
element = Fcons (Qleft, make_number (x)); |
|
|
result = Fcons (element, result); |
|
|
} |
|
|
|
|
|
if (geometry & YValue) |
|
|
{ |
|
|
Lisp_Object element; |
|
|
|
|
|
if (y >= 0 && (geometry & YNegative)) |
|
|
element = Fcons (Qtop, Fcons (Qminus, Fcons (make_number (-y), Qnil))); |
|
|
else if (y < 0 && ! (geometry & YNegative)) |
|
|
element = Fcons (Qtop, Fcons (Qplus, Fcons (make_number (y), Qnil))); |
|
|
else |
|
|
element = Fcons (Qtop, make_number (y)); |
|
|
result = Fcons (element, result); |
|
|
} |
|
|
|
|
|
if (geometry & WidthValue) |
|
|
result = Fcons (Fcons (Qwidth, make_number (width)), result); |
|
|
if (geometry & HeightValue) |
|
|
result = Fcons (Fcons (Qheight, make_number (height)), result); |
|
|
|
|
|
return result; |
|
|
} |
|
|
|
|
|
/* Calculate the desired size and position of this window, |
|
|
and return the flags saying which aspects were specified. |
|
|
|
|
|
This function does not make the coordinates positive. */ |
|
|
|
|
|
#define DEFAULT_ROWS 40 |
|
|
#define DEFAULT_COLS 80 |
|
|
|
|
|
static int |
|
|
x_figure_window_size (f, parms) |
|
|
struct frame *f; |
|
|
Lisp_Object parms; |
|
2173 |
{ |
{ |
2174 |
register Lisp_Object tem0, tem1, tem2; |
/* Try first to load cursor from application resource. */ |
2175 |
long window_prompting = 0; |
Cursor cursor = LoadImage ((HINSTANCE) GetModuleHandle(NULL), |
2176 |
|
name, IMAGE_CURSOR, 0, 0, |
2177 |
/* Default values if we fall through. |
LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED); |
2178 |
Actually, if that happens we should get |
if (!cursor) |
|
window manager prompting. */ |
|
|
SET_FRAME_WIDTH (f, DEFAULT_COLS); |
|
|
f->height = DEFAULT_ROWS; |
|
|
/* Window managers expect that if program-specified |
|
|
positions are not (0,0), they're intentional, not defaults. */ |
|
|
f->output_data.w32->top_pos = 0; |
|
|
f->output_data.w32->left_pos = 0; |
|
|
|
|
|
/* Ensure that old new_width and new_height will not override the |
|
|
values set here. */ |
|
|
FRAME_NEW_WIDTH (f) = 0; |
|
|
FRAME_NEW_HEIGHT (f) = 0; |
|
|
|
|
|
tem0 = w32_get_arg (parms, Qheight, 0, 0, RES_TYPE_NUMBER); |
|
|
tem1 = w32_get_arg (parms, Qwidth, 0, 0, RES_TYPE_NUMBER); |
|
|
tem2 = w32_get_arg (parms, Quser_size, 0, 0, RES_TYPE_NUMBER); |
|
|
if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) |
|
|
{ |
|
|
if (!EQ (tem0, Qunbound)) |
|
|
{ |
|
|
CHECK_NUMBER (tem0); |
|
|
f->height = XINT (tem0); |
|
|
} |
|
|
if (!EQ (tem1, Qunbound)) |
|
|
{ |
|
|
CHECK_NUMBER (tem1); |
|
|
SET_FRAME_WIDTH (f, XINT (tem1)); |
|
|
} |
|
|
if (!NILP (tem2) && !EQ (tem2, Qunbound)) |
|
|
window_prompting |= USSize; |
|
|
else |
|
|
window_prompting |= PSize; |
|
|
} |
|
|
|
|
|
f->output_data.w32->vertical_scroll_bar_extra |
|
|
= (!FRAME_HAS_VERTICAL_SCROLL_BARS (f) |
|
|
? 0 |
|
|
: FRAME_SCROLL_BAR_PIXEL_WIDTH (f) > 0 |
|
|
? FRAME_SCROLL_BAR_PIXEL_WIDTH (f) |
|
|
: (FRAME_SCROLL_BAR_COLS (f) * FONT_WIDTH (f->output_data.w32->font))); |
|
|
|
|
|
x_compute_fringe_widths (f, 0); |
|
|
|
|
|
f->output_data.w32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width); |
|
|
f->output_data.w32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height); |
|
|
|
|
|
tem0 = w32_get_arg (parms, Qtop, 0, 0, RES_TYPE_NUMBER); |
|
|
tem1 = w32_get_arg (parms, Qleft, 0, 0, RES_TYPE_NUMBER); |
|
|
tem2 = w32_get_arg (parms, Quser_position, 0, 0, RES_TYPE_NUMBER); |
|
|
if (! EQ (tem0, Qunbound) || ! EQ (tem1, Qunbound)) |
|
|
{ |
|
|
if (EQ (tem0, Qminus)) |
|
|
{ |
|
|
f->output_data.w32->top_pos = 0; |
|
|
window_prompting |= YNegative; |
|
|
} |
|
|
else if (CONSP (tem0) && EQ (XCAR (tem0), Qminus) |
|
|
&& CONSP (XCDR (tem0)) |
|
|
&& INTEGERP (XCAR (XCDR (tem0)))) |
|
|
{ |
|
|
f->output_data.w32->top_pos = - XINT (XCAR (XCDR (tem0))); |
|
|
window_prompting |= YNegative; |
|
|
} |
|
|
else if (CONSP (tem0) && EQ (XCAR (tem0), Qplus) |
|
|
&& CONSP (XCDR (tem0)) |
|
|
&& INTEGERP (XCAR (XCDR (tem0)))) |
|
|
{ |
|
|
f->output_data.w32->top_pos = XINT (XCAR (XCDR (tem0))); |
|
|
} |
|
|
else if (EQ (tem0, Qunbound)) |
|
|
f->output_data.w32->top_pos = 0; |
|
|
else |
|
|
{ |
|
|
CHECK_NUMBER (tem0); |
|
|
f->output_data.w32->top_pos = XINT (tem0); |
|
|
if (f->output_data.w32->top_pos < 0) |
|
|
window_prompting |= YNegative; |
|
|
} |
|
|
|
|
|
if (EQ (tem1, Qminus)) |
|
|
{ |
|
|
f->output_data.w32->left_pos = 0; |
|
|
window_prompting |= XNegative; |
|
|
} |
|
|
else if (CONSP (tem1) && EQ (XCAR (tem1), Qminus) |
|
|
&& CONSP (XCDR (tem1)) |
|
|
&& INTEGERP (XCAR (XCDR (tem1)))) |
|
|
{ |
|
|
f->output_data.w32->left_pos = - XINT (XCAR (XCDR (tem1))); |
|
|
window_prompting |= XNegative; |
|
|
} |
|
|
else if (CONSP (tem1) && EQ (XCAR (tem1), Qplus) |
|
|
&& CONSP (XCDR (tem1)) |
|
|
&& INTEGERP (XCAR (XCDR (tem1)))) |
|
|
{ |
|
|
f->output_data.w32->left_pos = XINT (XCAR (XCDR (tem1))); |
|
|
} |
|
|
else if (EQ (tem1, Qunbound)) |
|
|
f->output_data.w32->left_pos = 0; |
|
|
else |
|
|
{ |
|
|
CHECK_NUMBER (tem1); |
|
|
f->output_data.w32->left_pos = XINT (tem1); |
|
|
if (f->output_data.w32->left_pos < 0) |
|
|
window_prompting |= XNegative; |
|
|
} |
|
|
|
|
|
if (!NILP (tem2) && ! EQ (tem2, Qunbound)) |
|
|
window_prompting |= USPosition; |
|
|
else |
|
|
window_prompting |= PPosition; |
|
|
} |
|
|
|
|
|
if (f->output_data.w32->want_fullscreen != FULLSCREEN_NONE) |
|
2179 |
{ |
{ |
2180 |
int left, top; |
/* Then try to load a shared predefined cursor. */ |
2181 |
int width, height; |
cursor = LoadImage (NULL, name, IMAGE_CURSOR, 0, 0, |
2182 |
|
LR_DEFAULTCOLOR | LR_DEFAULTSIZE | LR_SHARED); |
|
/* It takes both for some WM:s to place it where we want */ |
|
|
window_prompting = USPosition | PPosition; |
|
|
x_fullscreen_adjust (f, &width, &height, &top, &left); |
|
|
f->width = width; |
|
|
f->height = height; |
|
|
f->output_data.w32->pixel_width = CHAR_TO_PIXEL_WIDTH (f, f->width); |
|
|
f->output_data.w32->pixel_height = CHAR_TO_PIXEL_HEIGHT (f, f->height); |
|
|
f->output_data.w32->left_pos = left; |
|
|
f->output_data.w32->top_pos = top; |
|
2183 |
} |
} |
2184 |
|
return cursor; |
|
return window_prompting; |
|
2185 |
} |
} |
2186 |
|
|
|
|
|
|
|
|
2187 |
extern LRESULT CALLBACK w32_wnd_proc (); |
extern LRESULT CALLBACK w32_wnd_proc (); |
2188 |
|
|
2189 |
BOOL |
BOOL |
2190 |
w32_init_class (hinst) |
w32_init_class (hinst) |
2191 |
HINSTANCE hinst; |
HINSTANCE hinst; |
2192 |
{ |
{ |
2198 |
wc.cbWndExtra = WND_EXTRA_BYTES; |
wc.cbWndExtra = WND_EXTRA_BYTES; |
2199 |
wc.hInstance = hinst; |
wc.hInstance = hinst; |
2200 |
wc.hIcon = LoadIcon (hinst, EMACS_CLASS); |
wc.hIcon = LoadIcon (hinst, EMACS_CLASS); |
2201 |
wc.hCursor = LoadCursor (NULL, IDC_ARROW); |
wc.hCursor = w32_load_cursor (IDC_ARROW); |
2202 |
wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */ |
wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */ |
2203 |
wc.lpszMenuName = NULL; |
wc.lpszMenuName = NULL; |
2204 |
wc.lpszClassName = EMACS_CLASS; |
wc.lpszClassName = EMACS_CLASS; |
2206 |
return (RegisterClass (&wc)); |
return (RegisterClass (&wc)); |
2207 |
} |
} |
2208 |
|
|
2209 |
HWND |
HWND |
2210 |
w32_createscrollbar (f, bar) |
w32_createscrollbar (f, bar) |
2211 |
struct frame *f; |
struct frame *f; |
2212 |
struct scroll_bar * bar; |
struct scroll_bar * bar; |
2214 |
return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, |
return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE, |
2215 |
/* Position and size of scroll bar. */ |
/* Position and size of scroll bar. */ |
2216 |
XINT(bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM, |
XINT(bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM, |
2217 |
XINT(bar->top), |
XINT(bar->top), |
2218 |
XINT(bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, |
XINT(bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2, |
2219 |
XINT(bar->height), |
XINT(bar->height), |
2220 |
FRAME_W32_WINDOW (f), |
FRAME_W32_WINDOW (f), |
2223 |
NULL)); |
NULL)); |
2224 |
} |
} |
2225 |
|
|
2226 |
void |
void |
2227 |
w32_createwindow (f) |
w32_createwindow (f) |
2228 |
struct frame *f; |
struct frame *f; |
2229 |
{ |
{ |
2233 |
rect.left = rect.top = 0; |
rect.left = rect.top = 0; |
2234 |
rect.right = PIXEL_WIDTH (f); |
rect.right = PIXEL_WIDTH (f); |
2235 |
rect.bottom = PIXEL_HEIGHT (f); |
rect.bottom = PIXEL_HEIGHT (f); |
2236 |
|
|
2237 |
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, |
AdjustWindowRect (&rect, f->output_data.w32->dwStyle, |
2238 |
FRAME_EXTERNAL_MENU_BAR (f)); |
FRAME_EXTERNAL_MENU_BAR (f)); |
2239 |
|
|
2240 |
/* Do first time app init */ |
/* Do first time app init */ |
2241 |
|
|
2242 |
if (!hprevinst) |
if (!hprevinst) |
2243 |
{ |
{ |
2244 |
w32_init_class (hinst); |
w32_init_class (hinst); |
2245 |
} |
} |
2246 |
|
|
2247 |
FRAME_W32_WINDOW (f) = hwnd |
FRAME_W32_WINDOW (f) = hwnd |
2248 |
= CreateWindow (EMACS_CLASS, |
= CreateWindow (EMACS_CLASS, |
2249 |
f->namebuf, |
f->namebuf, |
2267 |
|
|
2268 |
/* Enable drag-n-drop. */ |
/* Enable drag-n-drop. */ |
2269 |
DragAcceptFiles (hwnd, TRUE); |
DragAcceptFiles (hwnd, TRUE); |
2270 |
|
|
2271 |
/* Do this to discard the default setting specified by our parent. */ |
/* Do this to discard the default setting specified by our parent. */ |
2272 |
ShowWindow (hwnd, SW_HIDE); |
ShowWindow (hwnd, SW_HIDE); |
2273 |
} |
} |
2274 |
} |
} |
2275 |
|
|
2276 |
void |
void |
2277 |
my_post_msg (wmsg, hwnd, msg, wParam, lParam) |
my_post_msg (wmsg, hwnd, msg, wParam, lParam) |
2278 |
W32Msg * wmsg; |
W32Msg * wmsg; |
2279 |
HWND hwnd; |
HWND hwnd; |
2370 |
} |
} |
2371 |
|
|
2372 |
/* Emacs can lose focus while a modifier key has been pressed. When |
/* Emacs can lose focus while a modifier key has been pressed. When |
2373 |
it regains focus, be conservative and clear all modifiers since |
it regains focus, be conservative and clear all modifiers since |
2374 |
we cannot reconstruct the left and right modifier state. */ |
we cannot reconstruct the left and right modifier state. */ |
2375 |
static void |
static void |
2376 |
reset_modifiers () |
reset_modifiers () |
2425 |
if (!modifiers_recorded) |
if (!modifiers_recorded) |
2426 |
return; |
return; |
2427 |
|
|
2428 |
if (!(GetKeyState (VK_CONTROL) & 0x8000)) |
if (!(GetKeyState (VK_CONTROL) & 0x8000)) |
2429 |
modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0; |
modifiers[EMACS_RCONTROL] = modifiers[EMACS_LCONTROL] = 0; |
2430 |
|
|
2431 |
if (!(GetKeyState (VK_MENU) & 0x8000)) |
if (!(GetKeyState (VK_MENU) & 0x8000)) |
2432 |
modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0; |
modifiers[EMACS_RMENU] = modifiers[EMACS_LMENU] = 0; |
2433 |
} |
} |
2434 |
|
|
2638 |
HWND focus_window; |
HWND focus_window; |
2639 |
|
|
2640 |
msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); |
msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); |
2641 |
|
|
2642 |
while (GetMessage (&msg, NULL, 0, 0)) |
while (GetMessage (&msg, NULL, 0, 0)) |
2643 |
{ |
{ |
2644 |
if (msg.hwnd == NULL) |
if (msg.hwnd == NULL) |
2828 |
PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0); |
PostThreadMessage (dwWindowsThreadId, WM_NULL, 0, 0); |
2829 |
} |
} |
2830 |
|
|
2831 |
DWORD |
DWORD |
2832 |
w32_msg_worker (dw) |
w32_msg_worker (dw) |
2833 |
DWORD dw; |
DWORD dw; |
2834 |
{ |
{ |
2836 |
deferred_msg dummy_buf; |
deferred_msg dummy_buf; |
2837 |
|
|
2838 |
/* Ensure our message queue is created */ |
/* Ensure our message queue is created */ |
2839 |
|
|
2840 |
PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); |
PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); |
2841 |
|
|
2842 |
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) |
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) |
2843 |
abort (); |
abort (); |
2844 |
|
|
2917 |
|
|
2918 |
/* Main window procedure */ |
/* Main window procedure */ |
2919 |
|
|
2920 |
LRESULT CALLBACK |
LRESULT CALLBACK |
2921 |
w32_wnd_proc (hwnd, msg, wParam, lParam) |
w32_wnd_proc (hwnd, msg, wParam, lParam) |
2922 |
HWND hwnd; |
HWND hwnd; |
2923 |
UINT msg; |
UINT msg; |
2946 |
w32_clear_rect, because these functions must obtain a DC handle |
w32_clear_rect, because these functions must obtain a DC handle |
2947 |
from the frame struct using get_frame_dc which is thread-aware. */ |
from the frame struct using get_frame_dc which is thread-aware. */ |
2948 |
|
|
2949 |
switch (msg) |
switch (msg) |
2950 |
{ |
{ |
2951 |
case WM_ERASEBKGND: |
case WM_ERASEBKGND: |
2952 |
f = x_window_to_frame (dpyinfo, hwnd); |
f = x_window_to_frame (dpyinfo, hwnd); |
3015 |
leave_crit (); |
leave_crit (); |
3016 |
|
|
3017 |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3018 |
|
|
3019 |
return 0; |
return 0; |
3020 |
} |
} |
3021 |
|
|
3135 |
return 0; |
return 0; |
3136 |
break; |
break; |
3137 |
case VK_MENU: |
case VK_MENU: |
3138 |
if (NILP (Vw32_pass_alt_to_system)) |
if (NILP (Vw32_pass_alt_to_system)) |
3139 |
/* Prevent DefWindowProc from activating the menu bar if an |
/* Prevent DefWindowProc from activating the menu bar if an |
3140 |
Alt key is pressed and released by itself. */ |
Alt key is pressed and released by itself. */ |
3141 |
return 0; |
return 0; |
3142 |
windows_translate = 1; |
windows_translate = 1; |
3143 |
break; |
break; |
3144 |
case VK_CAPITAL: |
case VK_CAPITAL: |
3145 |
/* Decide whether to treat as modifier or function key. */ |
/* Decide whether to treat as modifier or function key. */ |
3146 |
if (NILP (Vw32_enable_caps_lock)) |
if (NILP (Vw32_enable_caps_lock)) |
3147 |
goto disable_lock_key; |
goto disable_lock_key; |
3178 |
w32_get_key_modifiers (wParam, lParam)); |
w32_get_key_modifiers (wParam, lParam)); |
3179 |
windows_translate = 1; |
windows_translate = 1; |
3180 |
break; |
break; |
3181 |
case VK_CONTROL: |
case VK_CONTROL: |
3182 |
case VK_SHIFT: |
case VK_SHIFT: |
3183 |
case VK_PROCESSKEY: /* Generated by IME. */ |
case VK_PROCESSKEY: /* Generated by IME. */ |
3184 |
windows_translate = 1; |
windows_translate = 1; |
3236 |
int add; |
int add; |
3237 |
int isdead = 0; |
int isdead = 0; |
3238 |
KEY_EVENT_RECORD key; |
KEY_EVENT_RECORD key; |
3239 |
|
|
3240 |
key.bKeyDown = TRUE; |
key.bKeyDown = TRUE; |
3241 |
key.wRepeatCount = 1; |
key.wRepeatCount = 1; |
3242 |
key.wVirtualKeyCode = wParam; |
key.wVirtualKeyCode = wParam; |
3277 |
} |
} |
3278 |
|
|
3279 |
/* Fall through */ |
/* Fall through */ |
3280 |
|
|
3281 |
case WM_SYSCHAR: |
case WM_SYSCHAR: |
3282 |
case WM_CHAR: |
case WM_CHAR: |
3283 |
post_character_message (hwnd, msg, wParam, lParam, |
post_character_message (hwnd, msg, wParam, lParam, |
3413 |
{ |
{ |
3414 |
if (up) ReleaseCapture (); |
if (up) ReleaseCapture (); |
3415 |
else SetCapture (hwnd); |
else SetCapture (hwnd); |
3416 |
button = (button == 0) ? LMOUSE : |
button = (button == 0) ? LMOUSE : |
3417 |
((button == 1) ? MMOUSE : RMOUSE); |
((button == 1) ? MMOUSE : RMOUSE); |
3418 |
if (up) |
if (up) |
3419 |
button_state &= ~button; |
button_state &= ~button; |
3421 |
button_state |= button; |
button_state |= button; |
3422 |
} |
} |
3423 |
} |
} |
3424 |
|
|
3425 |
wmsg.dwModifiers = w32_get_modifiers (); |
wmsg.dwModifiers = w32_get_modifiers (); |
3426 |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3427 |
|
|
3454 |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3455 |
return 0; |
return 0; |
3456 |
} |
} |
3457 |
|
|
3458 |
/* Hang onto mouse move and scroll messages for a bit, to avoid |
/* Hang onto mouse move and scroll messages for a bit, to avoid |
3459 |
sending such events to Emacs faster than it can process them. |
sending such events to Emacs faster than it can process them. |
3460 |
If we get more events before the timer from the first message |
If we get more events before the timer from the first message |
3472 |
saved_mouse_move_msg.msg.lParam = lParam; |
saved_mouse_move_msg.msg.lParam = lParam; |
3473 |
saved_mouse_move_msg.msg.time = GetMessageTime (); |
saved_mouse_move_msg.msg.time = GetMessageTime (); |
3474 |
saved_mouse_move_msg.dwModifiers = w32_get_modifiers (); |
saved_mouse_move_msg.dwModifiers = w32_get_modifiers (); |
3475 |
|
|
3476 |
return 0; |
return 0; |
3477 |
|
|
3478 |
case WM_MOUSEWHEEL: |
case WM_MOUSEWHEEL: |
3520 |
} |
} |
3521 |
} |
} |
3522 |
return 0; |
return 0; |
3523 |
|
|
3524 |
case WM_NCACTIVATE: |
case WM_NCACTIVATE: |
3525 |
/* Windows doesn't send us focus messages when putting up and |
/* Windows doesn't send us focus messages when putting up and |
3526 |
taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95. |
taking down a system popup dialog as for Ctrl-Alt-Del on Windows 95. |
3724 |
if (menu_free_timer) |
if (menu_free_timer) |
3725 |
{ |
{ |
3726 |
KillTimer (hwnd, menu_free_timer); |
KillTimer (hwnd, menu_free_timer); |
3727 |
menu_free_timer = 0; |
menu_free_timer = 0; |
3728 |
} |
} |
3729 |
} |
} |
3730 |
case WM_MOVE: |
case WM_MOVE: |
3749 |
|
|
3750 |
wp.length = sizeof (WINDOWPLACEMENT); |
wp.length = sizeof (WINDOWPLACEMENT); |
3751 |
GetWindowPlacement (hwnd, &wp); |
GetWindowPlacement (hwnd, &wp); |
3752 |
|
|
3753 |
if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0) |
if (wp.showCmd != SW_SHOWMINIMIZED && (lppos->flags & SWP_NOSIZE) == 0) |
3754 |
{ |
{ |
3755 |
RECT rect; |
RECT rect; |
3760 |
DWORD internal_border; |
DWORD internal_border; |
3761 |
DWORD scrollbar_extra; |
DWORD scrollbar_extra; |
3762 |
RECT wr; |
RECT wr; |
3763 |
|
|
3764 |
wp.length = sizeof(wp); |
wp.length = sizeof(wp); |
3765 |
GetWindowRect (hwnd, &wr); |
GetWindowRect (hwnd, &wr); |
3766 |
|
|
3767 |
enter_crit (); |
enter_crit (); |
3768 |
|
|
3769 |
font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX); |
font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX); |
3770 |
line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX); |
line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX); |
3771 |
internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX); |
internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX); |
3772 |
scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX); |
scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX); |
3773 |
|
|
3774 |
leave_crit (); |
leave_crit (); |
3775 |
|
|
3776 |
memset (&rect, 0, sizeof (rect)); |
memset (&rect, 0, sizeof (rect)); |
3777 |
AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE), |
AdjustWindowRect (&rect, GetWindowLong (hwnd, GWL_STYLE), |
3778 |
GetMenu (hwnd) != NULL); |
GetMenu (hwnd) != NULL); |
3779 |
|
|
3780 |
/* Force width and height of client area to be exact |
/* Force width and height of client area to be exact |
3785 |
hdiff = (lppos->cy - (rect.bottom - rect.top) |
hdiff = (lppos->cy - (rect.bottom - rect.top) |
3786 |
- 2 * internal_border) |
- 2 * internal_border) |
3787 |
% line_height; |
% line_height; |
3788 |
|
|
3789 |
if (wdiff || hdiff) |
if (wdiff || hdiff) |
3790 |
{ |
{ |
3791 |
/* For right/bottom sizing we can just fix the sizes. |
/* For right/bottom sizing we can just fix the sizes. |
3792 |
However for top/left sizing we will need to fix the X |
However for top/left sizing we will need to fix the X |
3793 |
and Y positions as well. */ |
and Y positions as well. */ |
3794 |
|
|
3795 |
lppos->cx -= wdiff; |
lppos->cx -= wdiff; |
3796 |
lppos->cy -= hdiff; |
lppos->cy -= hdiff; |
3797 |
|
|
3798 |
if (wp.showCmd != SW_SHOWMAXIMIZED |
if (wp.showCmd != SW_SHOWMAXIMIZED |
3799 |
&& (lppos->flags & SWP_NOMOVE) == 0) |
&& (lppos->flags & SWP_NOMOVE) == 0) |
3800 |
{ |
{ |
3801 |
if (lppos->x != wr.left || lppos->y != wr.top) |
if (lppos->x != wr.left || lppos->y != wr.top) |
3808 |
lppos->flags |= SWP_NOMOVE; |
lppos->flags |= SWP_NOMOVE; |
3809 |
} |
} |
3810 |
} |
} |
3811 |
|
|
3812 |
return 0; |
return 0; |
3813 |
} |
} |
3814 |
} |
} |
3815 |
} |
} |
3816 |
|
|
3817 |
goto dflt; |
goto dflt; |
3818 |
|
|
3819 |
case WM_GETMINMAXINFO: |
case WM_GETMINMAXINFO: |
3826 |
((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767; |
((LPMINMAXINFO) lParam)->ptMaxTrackSize.y = 32767; |
3827 |
return 0; |
return 0; |
3828 |
|
|
3829 |
|
case WM_SETCURSOR: |
3830 |
|
if (LOWORD (lParam) == HTCLIENT) |
3831 |
|
return 0; |
3832 |
|
|
3833 |
|
goto dflt; |
3834 |
|
|
3835 |
|
case WM_EMACS_SETCURSOR: |
3836 |
|
{ |
3837 |
|
Cursor cursor = (Cursor) wParam; |
3838 |
|
if (cursor) |
3839 |
|
SetCursor (cursor); |
3840 |
|
return 0; |
3841 |
|
} |
3842 |
|
|
3843 |
case WM_EMACS_CREATESCROLLBAR: |
case WM_EMACS_CREATESCROLLBAR: |
3844 |
return (LRESULT) w32_createscrollbar ((struct frame *) wParam, |
return (LRESULT) w32_createscrollbar ((struct frame *) wParam, |
3845 |
(struct scroll_bar *) lParam); |
(struct scroll_bar *) lParam); |
3905 |
CreateCaret (hwnd, NULL, 0, |
CreateCaret (hwnd, NULL, 0, |
3906 |
w32_system_caret_height); |
w32_system_caret_height); |
3907 |
} |
} |
3908 |
|
|
3909 |
if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y)) |
if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y)) |
3910 |
return 0; |
return 0; |
3911 |
/* Ensure visible caret gets turned on when requested. */ |
/* Ensure visible caret gets turned on when requested. */ |
3936 |
flags |= TPM_LEFTBUTTON; |
flags |= TPM_LEFTBUTTON; |
3937 |
else if (button_state & RMOUSE) |
else if (button_state & RMOUSE) |
3938 |
flags |= TPM_RIGHTBUTTON; |
flags |= TPM_RIGHTBUTTON; |
3939 |
|
|
3940 |
/* Remember we did a SetCapture on the initial mouse down event, |
/* Remember we did a SetCapture on the initial mouse down event, |
3941 |
so for safety, we make sure the capture is cancelled now. */ |
so for safety, we make sure the capture is cancelled now. */ |
3942 |
ReleaseCapture (); |
ReleaseCapture (); |
3947 |
f = x_window_to_frame (dpyinfo, hwnd); |
f = x_window_to_frame (dpyinfo, hwnd); |
3948 |
if (f) |
if (f) |
3949 |
f->output_data.w32->menubar_active = 1; |
f->output_data.w32->menubar_active = 1; |
3950 |
|
|
3951 |
if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y, |
if (TrackPopupMenu ((HMENU)wParam, flags, pos->x, pos->y, |
3952 |
0, hwnd, NULL)) |
0, hwnd, NULL)) |
3953 |
{ |
{ |
3954 |
MSG amsg; |
MSG amsg; |
3981 |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
my_post_msg (&wmsg, hwnd, msg, wParam, lParam); |
3982 |
return 0; |
return 0; |
3983 |
} |
} |
3984 |
|
|
3985 |
dflt: |
dflt: |
3986 |
return DefWindowProc (hwnd, msg, wParam, lParam); |
return DefWindowProc (hwnd, msg, wParam, lParam); |
3987 |
} |
} |
3988 |
|
|
3989 |
|
|
3990 |
/* The most common default return code for handled messages is 0. */ |
/* The most common default return code for handled messages is 0. */ |
3991 |
return 0; |
return 0; |
3992 |
} |
} |
3993 |
|
|
3994 |
void |
void |
3995 |
my_create_window (f) |
my_create_window (f) |
3996 |
struct frame * f; |
struct frame * f; |
3997 |
{ |
{ |
4007 |
indirectly via the Window thread, as we do not need to process Window |
indirectly via the Window thread, as we do not need to process Window |
4008 |
messages for the tooltip. Creating tooltips indirectly also creates |
messages for the tooltip. Creating tooltips indirectly also creates |
4009 |
deadlocks when tooltips are created for menu items. */ |
deadlocks when tooltips are created for menu items. */ |
4010 |
void |
void |
4011 |
my_create_tip_window (f) |
my_create_tip_window (f) |
4012 |
struct frame *f; |
struct frame *f; |
4013 |
{ |
{ |
4064 |
for the window manager, so GC relocation won't bother it. |
for the window manager, so GC relocation won't bother it. |
4065 |
|
|
4066 |
Elsewhere we specify the window name for the window manager. */ |
Elsewhere we specify the window name for the window manager. */ |
4067 |
|
|
4068 |
{ |
{ |
4069 |
char *str = (char *) XSTRING (Vx_resource_name)->data; |
char *str = (char *) SDATA (Vx_resource_name); |
4070 |
f->namebuf = (char *) xmalloc (strlen (str) + 1); |
f->namebuf = (char *) xmalloc (strlen (str) + 1); |
4071 |
strcpy (f->namebuf, str); |
strcpy (f->namebuf, str); |
4072 |
} |
} |
4133 |
? IconicState |
? IconicState |
4134 |
: NormalState)); |
: NormalState)); |
4135 |
|
|
4136 |
x_text_icon (f, (char *) XSTRING ((!NILP (f->icon_name) |
x_text_icon (f, (char *) SDATA ((!NILP (f->icon_name) |
4137 |
? f->icon_name |
? f->icon_name |
4138 |
: f->name))->data); |
: f->name))); |
4139 |
#endif |
#endif |
4140 |
|
|
4141 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
4188 |
#ifdef GLYPH_DEBUG |
#ifdef GLYPH_DEBUG |
4189 |
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); |
struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f); |
4190 |
#endif |
#endif |
4191 |
|
|
4192 |
x_free_frame_resources (f); |
x_free_frame_resources (f); |
4193 |
|
|
4194 |
/* Check that reference counts are indeed correct. */ |
/* Check that reference counts are indeed correct. */ |
4197 |
|
|
4198 |
return Qt; |
return Qt; |
4199 |
} |
} |
4200 |
|
|
4201 |
return Qnil; |
return Qnil; |
4202 |
} |
} |
4203 |
|
|
4222 |
int minibuffer_only = 0; |
int minibuffer_only = 0; |
4223 |
long window_prompting = 0; |
long window_prompting = 0; |
4224 |
int width, height; |
int width, height; |
4225 |
int count = BINDING_STACK_SIZE (); |
int count = SPECPDL_INDEX (); |
4226 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
4227 |
Lisp_Object display; |
Lisp_Object display; |
4228 |
struct w32_display_info *dpyinfo = NULL; |
struct w32_display_info *dpyinfo = NULL; |
4284 |
|
|
4285 |
/* Note that Windows does support scroll bars. */ |
/* Note that Windows does support scroll bars. */ |
4286 |
FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; |
FRAME_CAN_HAVE_SCROLL_BARS (f) = 1; |
4287 |
|
|
4288 |
/* By default, make scrollbars the system standard width. */ |
/* By default, make scrollbars the system standard width. */ |
4289 |
f->scroll_bar_pixel_width = GetSystemMetrics (SM_CXVSCROLL); |
f->scroll_bar_pixel_width = GetSystemMetrics (SM_CXVSCROLL); |
4290 |
|
|
4346 |
{ |
{ |
4347 |
tem = Fquery_fontset (font, Qnil); |
tem = Fquery_fontset (font, Qnil); |
4348 |
if (STRINGP (tem)) |
if (STRINGP (tem)) |
4349 |
font = x_new_fontset (f, XSTRING (tem)->data); |
font = x_new_fontset (f, SDATA (tem)); |
4350 |
else |
else |
4351 |
font = x_new_font (f, XSTRING (font)->data); |
font = x_new_font (f, SDATA (font)); |
4352 |
} |
} |
4353 |
/* Try out a font which we hope has bold and italic variations. */ |
/* Try out a font which we hope has bold and italic variations. */ |
4354 |
if (!STRINGP (font)) |
if (!STRINGP (font)) |
4362 |
if (! STRINGP (font)) |
if (! STRINGP (font)) |
4363 |
font = build_string ("Fixedsys"); |
font = build_string ("Fixedsys"); |
4364 |
|
|
4365 |
x_default_parameter (f, parms, Qfont, font, |
x_default_parameter (f, parms, Qfont, font, |
4366 |
"font", "Font", RES_TYPE_STRING); |
"font", "Font", RES_TYPE_STRING); |
4367 |
} |
} |
4368 |
|
|
4415 |
end up in init_iterator with a null face cache, which should not |
end up in init_iterator with a null face cache, which should not |
4416 |
happen. */ |
happen. */ |
4417 |
init_frame_faces (f); |
init_frame_faces (f); |
4418 |
|
|
4419 |
x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1), |
x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1), |
4420 |
"menuBar", "MenuBar", RES_TYPE_NUMBER); |
"menuBar", "MenuBar", RES_TYPE_NUMBER); |
4421 |
x_default_parameter (f, parms, Qtool_bar_lines, make_number (1), |
x_default_parameter (f, parms, Qtool_bar_lines, make_number (1), |
4431 |
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; |
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW; |
4432 |
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; |
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; |
4433 |
|
|
4434 |
/* Add the tool-bar height to the initial frame height so that the |
f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM); |
4435 |
user gets a text display area of the size he specified with -g or |
f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW); |
4436 |
via .Xdefaults. Later changes of the tool-bar height don't |
f->output_data.w32->modeline_cursor = w32_load_cursor (IDC_ARROW); |
4437 |
change the frame size. This is done so that users can create |
f->output_data.w32->hand_cursor = w32_load_cursor (IDC_HAND); |
4438 |
tall Emacs frames without having to guess how tall the tool-bar |
f->output_data.w32->hourglass_cursor = w32_load_cursor (IDC_WAIT); |
4439 |
will get. */ |
f->output_data.w32->horizontal_drag_cursor = w32_load_cursor (IDC_SIZEWE); |
|
if (FRAME_TOOL_BAR_LINES (f)) |
|
|
{ |
|
|
int margin, relief, bar_height; |
|
|
|
|
|
relief = (tool_bar_button_relief >= 0 |
|
|
? tool_bar_button_relief |
|
|
: DEFAULT_TOOL_BAR_BUTTON_RELIEF); |
|
|
|
|
|
if (INTEGERP (Vtool_bar_button_margin) |
|
|
&& XINT (Vtool_bar_button_margin) > 0) |
|
|
margin = XFASTINT (Vtool_bar_button_margin); |
|
|
else if (CONSP (Vtool_bar_button_margin) |
|
|
&& INTEGERP (XCDR (Vtool_bar_button_margin)) |
|
|
&& XINT (XCDR (Vtool_bar_button_margin)) > 0) |
|
|
margin = XFASTINT (XCDR (Vtool_bar_button_margin)); |
|
|
else |
|
|
margin = 0; |
|
|
|
|
|
bar_height = DEFAULT_TOOL_BAR_IMAGE_HEIGHT + 2 * margin + 2 * relief; |
|
|
f->height += (bar_height + CANON_Y_UNIT (f) - 1) / CANON_Y_UNIT (f); |
|
|
} |
|
|
|
|
|
window_prompting = x_figure_window_size (f, parms); |
|
|
|
|
|
if (window_prompting & XNegative) |
|
|
{ |
|
|
if (window_prompting & YNegative) |
|
|
f->output_data.w32->win_gravity = SouthEastGravity; |
|
|
else |
|
|
f->output_data.w32->win_gravity = NorthEastGravity; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (window_prompting & YNegative) |
|
|
f->output_data.w32->win_gravity = SouthWestGravity; |
|
|
else |
|
|
f->output_data.w32->win_gravity = NorthWestGravity; |
|
|
} |
|
4440 |
|
|
4441 |
f->output_data.w32->size_hint_flags = window_prompting; |
window_prompting = x_figure_window_size (f, parms, 1); |
4442 |
|
|
4443 |
tem = w32_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); |
tem = w32_get_arg (parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN); |
4444 |
f->no_split = minibuffer_only || EQ (tem, Qt); |
f->no_split = minibuffer_only || EQ (tem, Qt); |
4514 |
; |
; |
4515 |
} |
} |
4516 |
UNGCPRO; |
UNGCPRO; |
4517 |
|
|
4518 |
/* Make sure windows on this frame appear in calls to next-window |
/* Make sure windows on this frame appear in calls to next-window |
4519 |
and similar functions. */ |
and similar functions. */ |
4520 |
Vwindow_list = Qnil; |
Vwindow_list = Qnil; |
4521 |
|
|
4522 |
return unbind_to (count, frame); |
return unbind_to (count, frame); |
4523 |
} |
} |
4524 |
|
|
4599 |
for (tail = font_names; CONSP (tail); tail = XCDR (tail)) |
for (tail = font_names; CONSP (tail); tail = XCDR (tail)) |
4600 |
if (dpyinfo->font_table[i].name |
if (dpyinfo->font_table[i].name |
4601 |
&& (!strcmp (dpyinfo->font_table[i].name, |
&& (!strcmp (dpyinfo->font_table[i].name, |
4602 |
XSTRING (XCAR (tail))->data) |
SDATA (XCAR (tail))) |
4603 |
|| !strcmp (dpyinfo->font_table[i].full_name, |
|| !strcmp (dpyinfo->font_table[i].full_name, |
4604 |
XSTRING (XCAR (tail))->data))) |
SDATA (XCAR (tail))))) |
4605 |
return (dpyinfo->font_table + i); |
return (dpyinfo->font_table + i); |
4606 |
|
|
4607 |
fontname = (char *) XSTRING (XCAR (font_names))->data; |
fontname = (char *) SDATA (XCAR (font_names)); |
4608 |
} |
} |
4609 |
else if (w32_strict_fontnames) |
else if (w32_strict_fontnames) |
4610 |
{ |
{ |
4641 |
ended up with. */ |
ended up with. */ |
4642 |
return NULL; |
return NULL; |
4643 |
|
|
4644 |
/* Specify anti-aliasing to prevent Cleartype fonts being used, |
lf.lfQuality = DEFAULT_QUALITY; |
|
since those fonts leave garbage behind. */ |
|
|
lf.lfQuality = ANTIALIASED_QUALITY; |
|
4645 |
|
|
4646 |
font = (XFontStruct *) xmalloc (sizeof (XFontStruct)); |
font = (XFontStruct *) xmalloc (sizeof (XFontStruct)); |
4647 |
bzero (font, sizeof (*font)); |
bzero (font, sizeof (*font)); |
4653 |
|
|
4654 |
font->hfont = CreateFontIndirect (&lf); |
font->hfont = CreateFontIndirect (&lf); |
4655 |
|
|
4656 |
if (font->hfont == NULL) |
if (font->hfont == NULL) |
4657 |
{ |
{ |
4658 |
ok = FALSE; |
ok = FALSE; |
4659 |
} |
} |
4660 |
else |
else |
4661 |
{ |
{ |
4662 |
HDC hdc; |
HDC hdc; |
4663 |
HANDLE oldobj; |
HANDLE oldobj; |
4810 |
char *bdf_name, *bdf_file; |
char *bdf_name, *bdf_file; |
4811 |
Lisp_Object bdf_pair; |
Lisp_Object bdf_pair; |
4812 |
|
|
4813 |
bdf_name = XSTRING (XCAR (bdf_fonts))->data; |
bdf_name = SDATA (XCAR (bdf_fonts)); |
4814 |
bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); |
bdf_pair = Fassoc (XCAR (bdf_fonts), Vw32_bdf_filename_alist); |
4815 |
bdf_file = XSTRING (XCDR (bdf_pair))->data; |
bdf_file = SDATA (XCDR (bdf_pair)); |
4816 |
|
|
4817 |
retval = w32_load_bdf_font (f, bdf_name, size, bdf_file); |
retval = w32_load_bdf_font (f, bdf_name, size, bdf_file); |
4818 |
|
|
4826 |
} |
} |
4827 |
|
|
4828 |
|
|
4829 |
void |
void |
4830 |
w32_unload_font (dpyinfo, font) |
w32_unload_font (dpyinfo, font) |
4831 |
struct w32_display_info *dpyinfo; |
struct w32_display_info *dpyinfo; |
4832 |
XFontStruct * font; |
XFontStruct * font; |
4833 |
{ |
{ |
4834 |
if (font) |
if (font) |
4835 |
{ |
{ |
4836 |
if (font->per_char) xfree (font->per_char); |
if (font->per_char) xfree (font->per_char); |
4837 |
if (font->bdf) w32_free_bdf_font (font->bdf); |
if (font->bdf) w32_free_bdf_font (font->bdf); |
4864 |
* ) |
* ) |
4865 |
*/ |
*/ |
4866 |
|
|
4867 |
static LONG |
static LONG |
4868 |
x_to_w32_weight (lpw) |
x_to_w32_weight (lpw) |
4869 |
char * lpw; |
char * lpw; |
4870 |
{ |
{ |
4885 |
} |
} |
4886 |
|
|
4887 |
|
|
4888 |
static char * |
static char * |
4889 |
w32_to_x_weight (fnweight) |
w32_to_x_weight (fnweight) |
4890 |
int fnweight; |
int fnweight; |
4891 |
{ |
{ |
5072 |
sprintf (buf, "*-#%u", fncharset); |
sprintf (buf, "*-#%u", fncharset); |
5073 |
return buf; |
return buf; |
5074 |
} |
} |
5075 |
|
|
5076 |
{ |
{ |
5077 |
Lisp_Object rest; |
Lisp_Object rest; |
5078 |
char * best_match = NULL; |
char * best_match = NULL; |
5098 |
|| !SYMBOLP (XCAR (XCDR (this_entry)))) |
|| !SYMBOLP (XCAR (XCDR (this_entry)))) |
5099 |
continue; |
continue; |
5100 |
|
|
5101 |
x_charset = XSTRING (XCAR (this_entry))->data; |
x_charset = SDATA (XCAR (this_entry)); |
5102 |
w32_charset = XCAR (XCDR (this_entry)); |
w32_charset = XCAR (XCDR (this_entry)); |
5103 |
codepage = XCDR (XCDR (this_entry)); |
codepage = XCDR (XCDR (this_entry)); |
5104 |
|
|
5126 |
int this_enc = atoi (x_charset + 8); |
int this_enc = atoi (x_charset + 8); |
5127 |
if (this_enc > 0 && this_enc < best_enc) |
if (this_enc > 0 && this_enc < best_enc) |
5128 |
best_match = x_charset; |
best_match = x_charset; |
5129 |
} |
} |
5130 |
} |
} |
5131 |
} |
} |
5132 |
|
|
5233 |
sprintf (buf, "*-#%u", fncharset); |
sprintf (buf, "*-#%u", fncharset); |
5234 |
return Fcons (build_string (buf), Qnil); |
return Fcons (build_string (buf), Qnil); |
5235 |
} |
} |
5236 |
|
|
5237 |
{ |
{ |
5238 |
Lisp_Object rest; |
Lisp_Object rest; |
5239 |
/* Look through w32-charset-info-alist for the character set. |
/* Look through w32-charset-info-alist for the character set. |
5284 |
/* Get the Windows codepage corresponding to the specified font. The |
/* Get the Windows codepage corresponding to the specified font. The |
5285 |
charset info in the font name is used to look up |
charset info in the font name is used to look up |
5286 |
w32-charset-to-codepage-alist. */ |
w32-charset-to-codepage-alist. */ |
5287 |
int |
int |
5288 |
w32_codepage_for_font (char *fontname) |
w32_codepage_for_font (char *fontname) |
5289 |
{ |
{ |
5290 |
Lisp_Object codepage, entry; |
Lisp_Object codepage, entry; |
5335 |
} |
} |
5336 |
|
|
5337 |
|
|
5338 |
static BOOL |
static BOOL |
5339 |
w32_to_x_font (lplogfont, lpxstr, len, specific_charset) |
w32_to_x_font (lplogfont, lpxstr, len, specific_charset) |
5340 |
LOGFONT * lplogfont; |
LOGFONT * lplogfont; |
5341 |
char * lpxstr; |
char * lpxstr; |
5370 |
coding.src_multibyte = 0; |
coding.src_multibyte = 0; |
5371 |
coding.dst_multibyte = 1; |
coding.dst_multibyte = 1; |
5372 |
coding.mode |= CODING_MODE_LAST_BLOCK; |
coding.mode |= CODING_MODE_LAST_BLOCK; |
5373 |
|
/* We explicitely disable composition handling because selection |
5374 |
|
data should not contain any composition sequence. */ |
5375 |
|
coding.composing = COMPOSITION_DISABLED; |
5376 |
bufsz = decoding_buffer_size (&coding, LF_FACESIZE); |
bufsz = decoding_buffer_size (&coding, LF_FACESIZE); |
5377 |
|
|
5378 |
fontname = alloca(sizeof(*fontname) * bufsz); |
fontname = alloca(sizeof(*fontname) * bufsz); |
5418 |
? 'p' : 'c', /* spacing */ |
? 'p' : 'c', /* spacing */ |
5419 |
width_pixels, /* avg width */ |
width_pixels, /* avg width */ |
5420 |
specific_charset ? specific_charset |
specific_charset ? specific_charset |
5421 |
: w32_to_x_charset (lplogfont->lfCharSet) |
: w32_to_x_charset (lplogfont->lfCharSet) |
5422 |
/* charset registry and encoding */ |
/* charset registry and encoding */ |
5423 |
); |
); |
5424 |
|
|
5426 |
return (TRUE); |
return (TRUE); |
5427 |
} |
} |
5428 |
|
|
5429 |
static BOOL |
static BOOL |
5430 |
x_to_w32_font (lpxstr, lplogfont) |
x_to_w32_font (lpxstr, lplogfont) |
5431 |
char * lpxstr; |
char * lpxstr; |
5432 |
LOGFONT * lplogfont; |
LOGFONT * lplogfont; |
5461 |
* format: |
* format: |
5462 |
* "<font name>[:height in pixels[:width in pixels[:weight]]]" |
* "<font name>[:height in pixels[:width in pixels[:weight]]]" |
5463 |
*/ |
*/ |
5464 |
|
|
5465 |
if (*lpxstr == '-') |
if (*lpxstr == '-') |
5466 |
{ |
{ |
5467 |
int fields, tem; |
int fields, tem; |
5729 |
} |
} |
5730 |
|
|
5731 |
/* Assume parameter 1 is fully qualified, no wildcards. */ |
/* Assume parameter 1 is fully qualified, no wildcards. */ |
5732 |
static BOOL |
static BOOL |
5733 |
w32_font_match (fontname, pattern) |
w32_font_match (fontname, pattern) |
5734 |
char * fontname; |
char * fontname; |
5735 |
char * pattern; |
char * pattern; |
5791 |
font from each family, the second pass lists all the fonts from |
font from each family, the second pass lists all the fonts from |
5792 |
each family. */ |
each family. */ |
5793 |
|
|
5794 |
typedef struct enumfont_t |
typedef struct enumfont_t |
5795 |
{ |
{ |
5796 |
HDC hdc; |
HDC hdc; |
5797 |
int numFonts; |
int numFonts; |
5806 |
enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object); |
enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object); |
5807 |
|
|
5808 |
|
|
5809 |
static int CALLBACK |
static int CALLBACK |
5810 |
enum_font_cb2 (lplf, lptm, FontType, lpef) |
enum_font_cb2 (lplf, lptm, FontType, lpef) |
5811 |
ENUMLOGFONT * lplf; |
ENUMLOGFONT * lplf; |
5812 |
NEWTEXTMETRIC * lptm; |
NEWTEXTMETRIC * lptm; |
5881 |
|
|
5882 |
if (!NILP (lpef->pattern)) |
if (!NILP (lpef->pattern)) |
5883 |
{ |
{ |
5884 |
charset = xlfd_charset_of_font (XSTRING(lpef->pattern)->data); |
charset = xlfd_charset_of_font (SDATA (lpef->pattern)); |
5885 |
|
|
5886 |
/* We already checked charsets above, but DEFAULT_CHARSET |
/* We already checked charsets above, but DEFAULT_CHARSET |
5887 |
slipped through. So only allow exact matches for DEFAULT_CHARSET. */ |
slipped through. So only allow exact matches for DEFAULT_CHARSET. */ |
5901 |
for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list)) |
for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list)) |
5902 |
{ |
{ |
5903 |
Lisp_Object this_charset = Fcar (charset_list); |
Lisp_Object this_charset = Fcar (charset_list); |
5904 |
charset = XSTRING (this_charset)->data; |
charset = SDATA (this_charset); |
5905 |
|
|
5906 |
/* List bold and italic variations if w32-enable-synthesized-fonts |
/* List bold and italic variations if w32-enable-synthesized-fonts |
5907 |
is non-nil and this is a plain font. */ |
is non-nil and this is a plain font. */ |
5946 |
return; |
return; |
5947 |
|
|
5948 |
if (NILP (lpef->pattern) |
if (NILP (lpef->pattern) |
5949 |
|| w32_font_match (buf, XSTRING (lpef->pattern)->data)) |
|| w32_font_match (buf, SDATA (lpef->pattern))) |
5950 |
{ |
{ |
5951 |
/* Check if we already listed this font. This may happen if |
/* Check if we already listed this font. This may happen if |
5952 |
w32_enable_synthesized_fonts is non-nil, and there are real |
w32_enable_synthesized_fonts is non-nil, and there are real |
5962 |
} |
} |
5963 |
|
|
5964 |
|
|
5965 |
static int CALLBACK |
static int CALLBACK |
5966 |
enum_font_cb1 (lplf, lptm, FontType, lpef) |
enum_font_cb1 (lplf, lptm, FontType, lpef) |
5967 |
ENUMLOGFONT * lplf; |
ENUMLOGFONT * lplf; |
5968 |
NEWTEXTMETRIC * lptm; |
NEWTEXTMETRIC * lptm; |
6020 |
int n_fonts = 0; |
int n_fonts = 0; |
6021 |
|
|
6022 |
list = Vw32_bdf_filename_alist; |
list = Vw32_bdf_filename_alist; |
6023 |
ptnstr = XSTRING (pattern)->data; |
ptnstr = SDATA (pattern); |
6024 |
|
|
6025 |
for ( ; CONSP (list); list = XCDR (list)) |
for ( ; CONSP (list); list = XCDR (list)) |
6026 |
{ |
{ |
6027 |
tem = XCAR (list); |
tem = XCAR (list); |
6028 |
if (CONSP (tem)) |
if (CONSP (tem)) |
6029 |
fontname = XSTRING (XCAR (tem))->data; |
fontname = SDATA (XCAR (tem)); |
6030 |
else if (STRINGP (tem)) |
else if (STRINGP (tem)) |
6031 |
fontname = XSTRING (tem)->data; |
fontname = SDATA (tem); |
6032 |
else |
else |
6033 |
continue; |
continue; |
6034 |
|
|
6036 |
{ |
{ |
6037 |
newlist = Fcons (XCAR (tem), newlist); |
newlist = Fcons (XCAR (tem), newlist); |
6038 |
n_fonts++; |
n_fonts++; |
6039 |
if (n_fonts >= max_names) |
if (max_names >= 0 && n_fonts >= max_names) |
6040 |
break; |
break; |
6041 |
} |
} |
6042 |
} |
} |
6050 |
to be listed. Frame F NULL means we have not yet created any |
to be listed. Frame F NULL means we have not yet created any |
6051 |
frame, which means we can't get proper size info, as we don't have |
frame, which means we can't get proper size info, as we don't have |
6052 |
a device context to use for GetTextMetrics. |
a device context to use for GetTextMetrics. |
6053 |
MAXNAMES sets a limit on how many fonts to match. */ |
MAXNAMES sets a limit on how many fonts to match. If MAXNAMES is |
6054 |
|
negative, then all matching fonts are returned. */ |
6055 |
|
|
6056 |
Lisp_Object |
Lisp_Object |
6057 |
w32_list_fonts (f, pattern, size, maxnames) |
w32_list_fonts (f, pattern, size, maxnames) |
6081 |
|
|
6082 |
/* Avoid expensive EnumFontFamilies functions if we are not |
/* Avoid expensive EnumFontFamilies functions if we are not |
6083 |
going to be able to output one of these anyway. */ |
going to be able to output one of these anyway. */ |
6084 |
codepage = w32_codepage_for_font (XSTRING (tpat)->data); |
codepage = w32_codepage_for_font (SDATA (tpat)); |
6085 |
if (codepage != CP_8BIT && codepage != CP_UNICODE |
if (codepage != CP_8BIT && codepage != CP_UNICODE |
6086 |
&& codepage != CP_DEFAULT && codepage != CP_UNKNOWN |
&& codepage != CP_DEFAULT && codepage != CP_UNKNOWN |
6087 |
&& !IsValidCodePage(codepage)) |
&& !IsValidCodePage(codepage)) |
6108 |
/* Use EnumFontFamiliesEx where it is available, as it knows |
/* Use EnumFontFamiliesEx where it is available, as it knows |
6109 |
about character sets. Fall back to EnumFontFamilies for |
about character sets. Fall back to EnumFontFamilies for |
6110 |
older versions of NT that don't support the 'Ex function. */ |
older versions of NT that don't support the 'Ex function. */ |
6111 |
x_to_w32_font (XSTRING (tpat)->data, &ef.logfont); |
x_to_w32_font (SDATA (tpat), &ef.logfont); |
6112 |
{ |
{ |
6113 |
LOGFONT font_match_pattern; |
LOGFONT font_match_pattern; |
6114 |
HMODULE gdi32 = GetModuleHandle ("gdi32.dll"); |
HMODULE gdi32 = GetModuleHandle ("gdi32.dll"); |
6150 |
|
|
6151 |
newlist = second_best = Qnil; |
newlist = second_best = Qnil; |
6152 |
|
|
6153 |
/* Make a list of the fonts that have the right width. */ |
/* Make a list of the fonts that have the right width. */ |
6154 |
for (; CONSP (list); list = XCDR (list)) |
for (; CONSP (list); list = XCDR (list)) |
6155 |
{ |
{ |
6156 |
int found_size; |
int found_size; |
6164 |
{ |
{ |
6165 |
newlist = Fcons (XCAR (tem), newlist); |
newlist = Fcons (XCAR (tem), newlist); |
6166 |
n_fonts++; |
n_fonts++; |
6167 |
if (n_fonts >= maxnames) |
if (maxnames >= 0 && n_fonts >= maxnames) |
6168 |
break; |
break; |
6169 |
else |
else |
6170 |
continue; |
continue; |
6178 |
HDC hdc; |
HDC hdc; |
6179 |
HANDLE oldobj; |
HANDLE oldobj; |
6180 |
|
|
6181 |
if (!x_to_w32_font (XSTRING (XCAR (tem))->data, &lf)) |
if (!x_to_w32_font (SDATA (XCAR (tem)), &lf)) |
6182 |
continue; |
continue; |
6183 |
|
|
6184 |
BLOCK_INPUT; |
BLOCK_INPUT; |
6203 |
{ |
{ |
6204 |
newlist = Fcons (XCAR (tem), newlist); |
newlist = Fcons (XCAR (tem), newlist); |
6205 |
n_fonts++; |
n_fonts++; |
6206 |
if (n_fonts >= maxnames) |
if (maxnames >= 0 && n_fonts >= maxnames) |
6207 |
break; |
break; |
6208 |
} |
} |
6209 |
/* keep track of the closest matching size in case |
/* keep track of the closest matching size in case |
6212 |
{ |
{ |
6213 |
if (NILP (second_best)) |
if (NILP (second_best)) |
6214 |
second_best = tem; |
second_best = tem; |
6215 |
|
|
6216 |
else if (found_size < size) |
else if (found_size < size) |
6217 |
{ |
{ |
6218 |
if (XINT (XCDR (second_best)) > size |
if (XINT (XCDR (second_best)) > size |
6239 |
} |
} |
6240 |
|
|
6241 |
/* Include any bdf fonts. */ |
/* Include any bdf fonts. */ |
6242 |
if (n_fonts < maxnames) |
if (n_fonts < maxnames || maxnames < 0) |
6243 |
{ |
{ |
6244 |
Lisp_Object combined[2]; |
Lisp_Object combined[2]; |
6245 |
combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts); |
combined[0] = w32_list_bdf_fonts (pattern, maxnames - n_fonts); |
6325 |
for ( ; CONSP(filelist); filelist = XCDR (filelist)) |
for ( ; CONSP(filelist); filelist = XCDR (filelist)) |
6326 |
{ |
{ |
6327 |
Lisp_Object filename = XCAR (filelist); |
Lisp_Object filename = XCAR (filelist); |
6328 |
if (w32_BDF_to_x_font (XSTRING (filename)->data, fontname, 100)) |
if (w32_BDF_to_x_font (SDATA (filename), fontname, 100)) |
6329 |
store_in_alist (&list, build_string (fontname), filename); |
store_in_alist (&list, build_string (fontname), filename); |
6330 |
} |
} |
6331 |
return list; |
return list; |
6370 |
|
|
6371 |
CHECK_STRING (color); |
CHECK_STRING (color); |
6372 |
|
|
6373 |
if (w32_defined_color (f, XSTRING (color)->data, &foo, 0)) |
if (w32_defined_color (f, SDATA (color), &foo, 0)) |
6374 |
return Qt; |
return Qt; |
6375 |
else |
else |
6376 |
return Qnil; |
return Qnil; |
6386 |
|
|
6387 |
CHECK_STRING (color); |
CHECK_STRING (color); |
6388 |
|
|
6389 |
if (w32_defined_color (f, XSTRING (color)->data, &foo, 0)) |
if (w32_defined_color (f, SDATA (color), &foo, 0)) |
6390 |
{ |
{ |
6391 |
Lisp_Object rgb[3]; |
Lisp_Object rgb[3]; |
6392 |
|
|
6498 |
and because probably is more meaningful on Windows anyway */ |
and because probably is more meaningful on Windows anyway */ |
6499 |
if (cap < 0) |
if (cap < 0) |
6500 |
cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24); |
cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24); |
6501 |
|
|
6502 |
ReleaseDC (dpyinfo->root_window, hdc); |
ReleaseDC (dpyinfo->root_window, hdc); |
6503 |
|
|
6504 |
return make_number (cap); |
return make_number (cap); |
6505 |
} |
} |
6506 |
|
|
6572 |
int cap; |
int cap; |
6573 |
|
|
6574 |
hdc = GetDC (dpyinfo->root_window); |
hdc = GetDC (dpyinfo->root_window); |
6575 |
|
|
6576 |
cap = GetDeviceCaps (hdc, VERTSIZE); |
cap = GetDeviceCaps (hdc, VERTSIZE); |
6577 |
|
|
6578 |
ReleaseDC (dpyinfo->root_window, hdc); |
ReleaseDC (dpyinfo->root_window, hdc); |
6579 |
|
|
6580 |
return make_number (cap); |
return make_number (cap); |
6581 |
} |
} |
6582 |
|
|
6594 |
int cap; |
int cap; |
6595 |
|
|
6596 |
hdc = GetDC (dpyinfo->root_window); |
hdc = GetDC (dpyinfo->root_window); |
6597 |
|
|
6598 |
cap = GetDeviceCaps (hdc, HORZSIZE); |
cap = GetDeviceCaps (hdc, HORZSIZE); |
6599 |
|
|
6600 |
ReleaseDC (dpyinfo->root_window, hdc); |
ReleaseDC (dpyinfo->root_window, hdc); |
6601 |
|
|
6602 |
return make_number (cap); |
return make_number (cap); |
6603 |
} |
} |
6604 |
|
|
6717 |
validate_x_resource_name (); |
validate_x_resource_name (); |
6718 |
|
|
6719 |
dpyinfo = w32_term_init (name, (unsigned char *)0, |
dpyinfo = w32_term_init (name, (unsigned char *)0, |
6720 |
(char *) XSTRING (Vx_resource_name)->data); |
(char *) SDATA (Vx_resource_name)); |
6721 |
|
|
6722 |
if (dpyinfo == 0) |
if (dpyinfo == 0) |
6723 |
error ("Cannot connect to server %s", XSTRING (name)->data); |
error ("Cannot connect to server %s", SDATA (name)); |
6724 |
|
|
6725 |
w32_in_use = 1; |
w32_in_use = 1; |
6726 |
XSETFASTINT (Vwindow_system_version, 3); |
XSETFASTINT (Vwindow_system_version, 3); |
6775 |
Vw32_color_map = Fw32_default_color_map (); |
Vw32_color_map = Fw32_default_color_map (); |
6776 |
|
|
6777 |
if (! NILP (xrm_string)) |
if (! NILP (xrm_string)) |
6778 |
xrm_option = (unsigned char *) XSTRING (xrm_string)->data; |
xrm_option = (unsigned char *) SDATA (xrm_string); |
6779 |
else |
else |
6780 |
xrm_option = (unsigned char *) 0; |
xrm_option = (unsigned char *) 0; |
6781 |
|
|
6784 |
{ |
{ |
6785 |
char basename[ MAX_PATH ], *str; |
char basename[ MAX_PATH ], *str; |
6786 |
|
|
6787 |
strcpy (basename, XSTRING (Vinvocation_name)->data); |
strcpy (basename, SDATA (Vinvocation_name)); |
6788 |
str = strrchr (basename, '.'); |
str = strrchr (basename, '.'); |
6789 |
if (str) *str = 0; |
if (str) *str = 0; |
6790 |
Vinvocation_name = build_string (basename); |
Vinvocation_name = build_string (basename); |
6796 |
/* This is what opens the connection and sets x_current_display. |
/* This is what opens the connection and sets x_current_display. |
6797 |
This also initializes many symbols, such as those used for input. */ |
This also initializes many symbols, such as those used for input. */ |
6798 |
dpyinfo = w32_term_init (display, xrm_option, |
dpyinfo = w32_term_init (display, xrm_option, |
6799 |
(char *) XSTRING (Vx_resource_name)->data); |
(char *) SDATA (Vx_resource_name)); |
6800 |
|
|
6801 |
if (dpyinfo == 0) |
if (dpyinfo == 0) |
6802 |
{ |
{ |
6803 |
if (!NILP (must_succeed)) |
if (!NILP (must_succeed)) |
6804 |
fatal ("Cannot connect to server %s.\n", |
fatal ("Cannot connect to server %s.\n", |
6805 |
XSTRING (display)->data); |
SDATA (display)); |
6806 |
else |
else |
6807 |
error ("Cannot connect to server %s", XSTRING (display)->data); |
error ("Cannot connect to server %s", SDATA (display)); |
6808 |
} |
} |
6809 |
|
|
6810 |
w32_in_use = 1; |
w32_in_use = 1; |
6963 |
Lisp_Object object; |
Lisp_Object object; |
6964 |
{ |
{ |
6965 |
int valid_p = 0; |
int valid_p = 0; |
6966 |
|
|
6967 |
if (CONSP (object) && EQ (XCAR (object), Qimage)) |
if (CONSP (object) && EQ (XCAR (object), Qimage)) |
6968 |
{ |
{ |
6969 |
Lisp_Object tem; |
Lisp_Object tem; |
7088 |
|
|
7089 |
/* Find key in KEYWORDS. Error if not found. */ |
/* Find key in KEYWORDS. Error if not found. */ |
7090 |
for (i = 0; i < nkeywords; ++i) |
for (i = 0; i < nkeywords; ++i) |
7091 |
if (strcmp (keywords[i].name, XSTRING (SYMBOL_NAME (key))->data) == 0) |
if (strcmp (keywords[i].name, SDATA (SYMBOL_NAME (key))) == 0) |
7092 |
break; |
break; |
7093 |
|
|
7094 |
if (i == nkeywords) |
if (i == nkeywords) |
7098 |
was found more than once, it's an error. */ |
was found more than once, it's an error. */ |
7099 |
keywords[i].value = value; |
keywords[i].value = value; |
7100 |
++keywords[i].count; |
++keywords[i].count; |
7101 |
|
|
7102 |
if (keywords[i].count > 1) |
if (keywords[i].count > 1) |
7103 |
return 0; |
return 0; |
7104 |
|
|
7153 |
|
|
7154 |
case IMAGE_FUNCTION_VALUE: |
case IMAGE_FUNCTION_VALUE: |
7155 |
value = indirect_function (value); |
value = indirect_function (value); |
7156 |
if (SUBRP (value) |
if (SUBRP (value) |
7157 |
|| COMPILEDP (value) |
|| COMPILEDP (value) |
7158 |
|| (CONSP (value) && EQ (XCAR (value), Qlambda))) |
|| (CONSP (value) && EQ (XCAR (value), Qlambda))) |
7159 |
break; |
break; |
7202 |
int *found; |
int *found; |
7203 |
{ |
{ |
7204 |
Lisp_Object tail; |
Lisp_Object tail; |
7205 |
|
|
7206 |
xassert (valid_image_p (spec)); |
xassert (valid_image_p (spec)); |
7207 |
|
|
7208 |
for (tail = XCDR (spec); |
for (tail = XCDR (spec); |
7216 |
return XCAR (XCDR (tail)); |
return XCAR (XCDR (tail)); |
7217 |
} |
} |
7218 |
} |
} |
7219 |
|
|
7220 |
if (found) |
if (found) |
7221 |
*found = 0; |
*found = 0; |
7222 |
return Qnil; |
return Qnil; |
7223 |
} |
} |
7224 |
|
|
7225 |
|
|
7226 |
DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0, |
DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0, |
7227 |
doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT). |
doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT). |
7242 |
struct image *img = IMAGE_FROM_ID (f, id); |
struct image *img = IMAGE_FROM_ID (f, id); |
7243 |
int width = img->width + 2 * img->hmargin; |
int width = img->width + 2 * img->hmargin; |
7244 |
int height = img->height + 2 * img->vmargin; |
int height = img->height + 2 * img->vmargin; |
7245 |
|
|
7246 |
if (NILP (pixels)) |
if (NILP (pixels)) |
7247 |
size = Fcons (make_float ((double) width / CANON_X_UNIT (f)), |
size = Fcons (make_float ((double) width / CANON_X_UNIT (f)), |
7248 |
make_float ((double) height / CANON_Y_UNIT (f))); |
make_float ((double) height / CANON_Y_UNIT (f))); |
7287 |
|
|
7288 |
static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); |
static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); |
7289 |
static void free_image P_ ((struct frame *f, struct image *img)); |
static void free_image P_ ((struct frame *f, struct image *img)); |
7290 |
|
static void x_destroy_x_image P_ ((XImage *)); |
7291 |
|
|
7292 |
|
|
7293 |
/* Allocate and return a new image structure for image specification |
/* Allocate and return a new image structure for image specification |
7299 |
unsigned hash; |
unsigned hash; |
7300 |
{ |
{ |
7301 |
struct image *img = (struct image *) xmalloc (sizeof *img); |
struct image *img = (struct image *) xmalloc (sizeof *img); |
7302 |
|
|
7303 |
xassert (valid_image_p (spec)); |
xassert (valid_image_p (spec)); |
7304 |
bzero (img, sizeof *img); |
bzero (img, sizeof *img); |
7305 |
img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); |
img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); |
7360 |
if (img->pixmap == 0 && !img->load_failed_p) |
if (img->pixmap == 0 && !img->load_failed_p) |
7361 |
img->load_failed_p = img->type->load (f, img) == 0; |
img->load_failed_p = img->type->load (f, img) == 0; |
7362 |
} |
} |
7363 |
|
|
7364 |
|
|
7365 |
/* Value is the number of pixels for the ascent of image IMG when |
/* Value is the number of pixels for the ascent of image IMG when |
7366 |
drawn in face FACE. */ |
drawn in face FACE. */ |
7394 |
/* Find the "best" corner color of a bitmap. XIMG is assumed to a device |
/* Find the "best" corner color of a bitmap. XIMG is assumed to a device |
7395 |
context with the bitmap selected. */ |
context with the bitmap selected. */ |
7396 |
static COLORREF |
static COLORREF |
7397 |
four_corners_best (ximg, width, height) |
four_corners_best (img_dc, width, height) |
7398 |
HDC ximg; |
HDC img_dc; |
7399 |
unsigned long width, height; |
unsigned long width, height; |
7400 |
{ |
{ |
7401 |
COLORREF corners[4], best; |
COLORREF corners[4], best; |
7402 |
int i, best_count; |
int i, best_count; |
7403 |
|
|
7404 |
/* Get the colors at the corners of ximg. */ |
/* Get the colors at the corners of img_dc. */ |
7405 |
corners[0] = GetPixel (ximg, 0, 0); |
corners[0] = GetPixel (img_dc, 0, 0); |
7406 |
corners[1] = GetPixel (ximg, width - 1, 0); |
corners[1] = GetPixel (img_dc, width - 1, 0); |
7407 |
corners[2] = GetPixel (ximg, width - 1, height - 1); |
corners[2] = GetPixel (img_dc, width - 1, height - 1); |
7408 |
corners[3] = GetPixel (ximg, 0, height - 1); |
corners[3] = GetPixel (img_dc, 0, height - 1); |
7409 |
|
|
7410 |
/* Choose the most frequently found color as background. */ |
/* Choose the most frequently found color as background. */ |
7411 |
for (i = best_count = 0; i < 4; ++i) |
for (i = best_count = 0; i < 4; ++i) |
7412 |
{ |
{ |
7413 |
int j, n; |
int j, n; |
7414 |
|
|
7415 |
for (j = n = 0; j < 4; ++j) |
for (j = n = 0; j < 4; ++j) |
7416 |
if (corners[i] == corners[j]) |
if (corners[i] == corners[j]) |
7417 |
++n; |
++n; |
7424 |
} |
} |
7425 |
|
|
7426 |
/* Return the `background' field of IMG. If IMG doesn't have one yet, |
/* Return the `background' field of IMG. If IMG doesn't have one yet, |
7427 |
it is guessed heuristically. If non-zero, XIMG is an existing XImage |
it is guessed heuristically. If non-zero, IMG_DC is an existing |
7428 |
object to use for the heuristic. */ |
device context with the image selected to use for the heuristic. */ |
7429 |
|
|
7430 |
unsigned long |
unsigned long |
7431 |
image_background (img, f, ximg) |
image_background (img, f, img_dc) |
7432 |
struct image *img; |
struct image *img; |
7433 |
struct frame *f; |
struct frame *f; |
7434 |
XImage *ximg; |
HDC img_dc; |
7435 |
{ |
{ |
7436 |
if (! img->background_valid) |
if (! img->background_valid) |
7437 |
/* IMG doesn't have a background yet, try to guess a reasonable value. */ |
/* IMG doesn't have a background yet, try to guess a reasonable value. */ |
7438 |
{ |
{ |
7439 |
#if 0 /* TODO: Image support. */ |
int free_ximg = !img_dc; |
7440 |
int free_ximg = !ximg; |
HGDIOBJ prev; |
7441 |
|
|
7442 |
|
if (free_ximg) |
7443 |
|
{ |
7444 |
|
HDC frame_dc = get_frame_dc (f); |
7445 |
|
img_dc = CreateCompatibleDC (frame_dc); |
7446 |
|
release_frame_dc (f, frame_dc); |
7447 |
|
|
7448 |
if (! ximg) |
prev = SelectObject (img_dc, img->pixmap); |
7449 |
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, |
} |
|
0, 0, img->width, img->height, ~0, ZPixmap); |
|
7450 |
|
|
7451 |
img->background = four_corners_best (ximg, img->width, img->height); |
img->background = four_corners_best (img_dc, img->width, img->height); |
7452 |
|
|
7453 |
if (free_ximg) |
if (free_ximg) |
7454 |
XDestroyImage (ximg); |
{ |
7455 |
|
SelectObject (img_dc, prev); |
7456 |
|
DeleteDC (img_dc); |
7457 |
|
} |
7458 |
|
|
7459 |
img->background_valid = 1; |
img->background_valid = 1; |
|
#endif |
|
7460 |
} |
} |
7461 |
|
|
7462 |
return img->background; |
return img->background; |
7470 |
image_background_transparent (img, f, mask) |
image_background_transparent (img, f, mask) |
7471 |
struct image *img; |
struct image *img; |
7472 |
struct frame *f; |
struct frame *f; |
7473 |
XImage *mask; |
HDC mask; |
7474 |
{ |
{ |
7475 |
if (! img->background_transparent_valid) |
if (! img->background_transparent_valid) |
7476 |
/* IMG doesn't have a background yet, try to guess a reasonable value. */ |
/* IMG doesn't have a background yet, try to guess a reasonable value. */ |
7477 |
{ |
{ |
|
#if 0 /* TODO: Image support. */ |
|
7478 |
if (img->mask) |
if (img->mask) |
7479 |
{ |
{ |
7480 |
int free_mask = !mask; |
int free_mask = !mask; |
7481 |
|
HGDIOBJ prev; |
7482 |
|
|
7483 |
if (! mask) |
if (free_mask) |
7484 |
mask = XGetImage (FRAME_X_DISPLAY (f), img->mask, |
{ |
7485 |
0, 0, img->width, img->height, ~0, ZPixmap); |
HDC frame_dc = get_frame_dc (f); |
7486 |
|
mask = CreateCompatibleDC (frame_dc); |
7487 |
|
release_frame_dc (f, frame_dc); |
7488 |
|
|
7489 |
|
prev = SelectObject (mask, img->mask); |
7490 |
|
} |
7491 |
|
|
7492 |
img->background_transparent |
img->background_transparent |
7493 |
= !four_corners_best (mask, img->width, img->height); |
= !four_corners_best (mask, img->width, img->height); |
7494 |
|
|
7495 |
if (free_mask) |
if (free_mask) |
7496 |
XDestroyImage (mask); |
{ |
7497 |
|
SelectObject (mask, prev); |
7498 |
|
DeleteDC (mask); |
7499 |
|
} |
7500 |
} |
} |
7501 |
else |
else |
|
#endif |
|
7502 |
img->background_transparent = 0; |
img->background_transparent = 0; |
7503 |
|
|
7504 |
img->background_transparent_valid = 1; |
img->background_transparent_valid = 1; |
7545 |
img->mask = NULL; |
img->mask = NULL; |
7546 |
img->background_transparent_valid = 0; |
img->background_transparent_valid = 0; |
7547 |
} |
} |
7548 |
|
|
7549 |
if (colors_p && img->ncolors) |
if (colors_p && img->ncolors) |
7550 |
{ |
{ |
7551 |
#if 0 /* TODO: color table support. */ |
#if 0 /* TODO: color table support. */ |
7577 |
#if 0 /* TODO: color table support */ |
#if 0 /* TODO: color table support */ |
7578 |
|
|
7579 |
int class = FRAME_W32_DISPLAY_INFO (f)->visual->class; |
int class = FRAME_W32_DISPLAY_INFO (f)->visual->class; |
7580 |
|
|
7581 |
/* If display has an immutable color map, freeing colors is not |
/* If display has an immutable color map, freeing colors is not |
7582 |
necessary and some servers don't allow it. So don't do it. */ |
necessary and some servers don't allow it. So don't do it. */ |
7583 |
if (class != StaticColor |
if (class != StaticColor |
7592 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
7593 |
} |
} |
7594 |
#endif |
#endif |
7595 |
|
|
7596 |
xfree (img->colors); |
xfree (img->colors); |
7597 |
img->colors = NULL; |
img->colors = NULL; |
7598 |
img->ncolors = 0; |
img->ncolors = 0; |
7617 |
|
|
7618 |
xassert (STRINGP (color_name)); |
xassert (STRINGP (color_name)); |
7619 |
|
|
7620 |
if (w32_defined_color (f, XSTRING (color_name)->data, &color, 1)) |
if (w32_defined_color (f, SDATA (color_name), &color, 1)) |
7621 |
{ |
{ |
7622 |
/* This isn't called frequently so we get away with simply |
/* This isn't called frequently so we get away with simply |
7623 |
reallocating the color vector to the needed size, here. */ |
reallocating the color vector to the needed size, here. */ |
7641 |
|
|
7642 |
static void cache_image P_ ((struct frame *f, struct image *img)); |
static void cache_image P_ ((struct frame *f, struct image *img)); |
7643 |
static void postprocess_image P_ ((struct frame *, struct image *)); |
static void postprocess_image P_ ((struct frame *, struct image *)); |
7644 |
|
static void x_disable_image P_ ((struct frame *, struct image *)); |
7645 |
|
|
7646 |
|
|
7647 |
/* Return a new, initialized image cache that is allocated from the |
/* Return a new, initialized image cache that is allocated from the |
7652 |
{ |
{ |
7653 |
struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c); |
struct image_cache *c = (struct image_cache *) xmalloc (sizeof *c); |
7654 |
int size; |
int size; |
7655 |
|
|
7656 |
bzero (c, sizeof *c); |
bzero (c, sizeof *c); |
7657 |
c->size = 50; |
c->size = 50; |
7658 |
c->images = (struct image **) xmalloc (c->size * sizeof *c->images); |
c->images = (struct image **) xmalloc (c->size * sizeof *c->images); |
7677 |
|
|
7678 |
/* Cache should not be referenced by any frame when freed. */ |
/* Cache should not be referenced by any frame when freed. */ |
7679 |
xassert (c->refcount == 0); |
xassert (c->refcount == 0); |
7680 |
|
|
7681 |
for (i = 0; i < c->used; ++i) |
for (i = 0; i < c->used; ++i) |
7682 |
free_image (f, c->images[i]); |
free_image (f, c->images[i]); |
7683 |
xfree (c->images); |
xfree (c->images); |
7710 |
|
|
7711 |
EMACS_GET_TIME (t); |
EMACS_GET_TIME (t); |
7712 |
old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); |
old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); |
7713 |
|
|
7714 |
/* Block input so that we won't be interrupted by a SIGIO |
/* Block input so that we won't be interrupted by a SIGIO |
7715 |
while being in an inconsistent state. */ |
while being in an inconsistent state. */ |
7716 |
BLOCK_INPUT; |
BLOCK_INPUT; |
7717 |
|
|
7718 |
for (i = nfreed = 0; i < c->used; ++i) |
for (i = nfreed = 0; i < c->used; ++i) |
7719 |
{ |
{ |
7720 |
struct image *img = c->images[i]; |
struct image *img = c->images[i]; |
7733 |
if (nfreed) |
if (nfreed) |
7734 |
{ |
{ |
7735 |
Lisp_Object tail, frame; |
Lisp_Object tail, frame; |
7736 |
|
|
7737 |
FOR_EACH_FRAME (tail, frame) |
FOR_EACH_FRAME (tail, frame) |
7738 |
{ |
{ |
7739 |
struct frame *f = XFRAME (frame); |
struct frame *f = XFRAME (frame); |
7761 |
if (EQ (frame, Qt)) |
if (EQ (frame, Qt)) |
7762 |
{ |
{ |
7763 |
Lisp_Object tail; |
Lisp_Object tail; |
7764 |
|
|
7765 |
FOR_EACH_FRAME (tail, frame) |
FOR_EACH_FRAME (tail, frame) |
7766 |
if (FRAME_W32_P (XFRAME (frame))) |
if (FRAME_W32_P (XFRAME (frame))) |
7767 |
clear_image_cache (XFRAME (frame), 1); |
clear_image_cache (XFRAME (frame), 1); |
7781 |
struct frame *f; |
struct frame *f; |
7782 |
struct image *img; |
struct image *img; |
7783 |
{ |
{ |
|
#if 0 /* TODO: image support. */ |
|
7784 |
/* Manipulation of the image's mask. */ |
/* Manipulation of the image's mask. */ |
7785 |
if (img->pixmap) |
if (img->pixmap) |
7786 |
{ |
{ |
7788 |
Lisp_Object mask; |
Lisp_Object mask; |
7789 |
|
|
7790 |
spec = img->spec; |
spec = img->spec; |
7791 |
|
|
7792 |
/* `:heuristic-mask t' |
/* `:heuristic-mask t' |
7793 |
`:mask heuristic' |
`:mask heuristic' |
7794 |
means build a mask heuristically. |
means build a mask heuristically. |
7798 |
image. |
image. |
7799 |
`:mask nil' |
`:mask nil' |
7800 |
means remove a mask, if any. */ |
means remove a mask, if any. */ |
7801 |
|
|
7802 |
mask = image_spec_value (spec, QCheuristic_mask, NULL); |
mask = image_spec_value (spec, QCheuristic_mask, NULL); |
7803 |
if (!NILP (mask)) |
if (!NILP (mask)) |
7804 |
x_build_heuristic_mask (f, img, mask); |
x_build_heuristic_mask (f, img, mask); |
7805 |
else |
else |
7806 |
{ |
{ |
7807 |
int found_p; |
int found_p; |
7808 |
|
|
7809 |
mask = image_spec_value (spec, QCmask, &found_p); |
mask = image_spec_value (spec, QCmask, &found_p); |
7810 |
|
|
7811 |
if (EQ (mask, Qheuristic)) |
if (EQ (mask, Qheuristic)) |
7812 |
x_build_heuristic_mask (f, img, Qt); |
x_build_heuristic_mask (f, img, Qt); |
7813 |
else if (CONSP (mask) |
else if (CONSP (mask) |
7824 |
img->mask = NULL; |
img->mask = NULL; |
7825 |
} |
} |
7826 |
} |
} |
7827 |
|
|
7828 |
|
|
7829 |
/* Should we apply an image transformation algorithm? */ |
/* Should we apply an image transformation algorithm? */ |
7830 |
conversion = image_spec_value (spec, QCconversion, NULL); |
conversion = image_spec_value (spec, QCconversion, NULL); |
7831 |
if (EQ (conversion, Qdisabled)) |
if (EQ (conversion, Qdisabled)) |
7845 |
Fplist_get (tem, QCcolor_adjustment)); |
Fplist_get (tem, QCcolor_adjustment)); |
7846 |
} |
} |
7847 |
} |
} |
|
#endif |
|
7848 |
} |
} |
7849 |
|
|
7850 |
|
|
7867 |
specification. */ |
specification. */ |
7868 |
xassert (FRAME_WINDOW_P (f)); |
xassert (FRAME_WINDOW_P (f)); |
7869 |
xassert (valid_image_p (spec)); |
xassert (valid_image_p (spec)); |
7870 |
|
|
7871 |
GCPRO1 (spec); |
GCPRO1 (spec); |
7872 |
|
|
7873 |
/* Look up SPEC in the hash table of the image cache. */ |
/* Look up SPEC in the hash table of the image cache. */ |
7905 |
else |
else |
7906 |
{ |
{ |
7907 |
/* Handle image type independent image attributes |
/* Handle image type independent image attributes |
7908 |
`:ascent PERCENT', `:margin MARGIN', `:relief RELIEF', |
`:ascent ASCENT', `:margin MARGIN', `:relief RELIEF', |
7909 |
`:background COLOR'. */ |
`:background COLOR'. */ |
7910 |
Lisp_Object ascent, margin, relief, bg; |
Lisp_Object ascent, margin, relief, bg; |
7911 |
|
|
7926 |
if (XINT (XCDR (margin)) > 0) |
if (XINT (XCDR (margin)) > 0) |
7927 |
img->vmargin = XFASTINT (XCDR (margin)); |
img->vmargin = XFASTINT (XCDR (margin)); |
7928 |
} |
} |
7929 |
|
|
7930 |
relief = image_spec_value (spec, QCrelief, NULL); |
relief = image_spec_value (spec, QCrelief, NULL); |
7931 |
if (INTEGERP (relief)) |
if (INTEGERP (relief)) |
7932 |
{ |
{ |
7960 |
/* We're using IMG, so set its timestamp to `now'. */ |
/* We're using IMG, so set its timestamp to `now'. */ |
7961 |
EMACS_GET_TIME (now); |
EMACS_GET_TIME (now); |
7962 |
img->timestamp = EMACS_SECS (now); |
img->timestamp = EMACS_SECS (now); |
7963 |
|
|
7964 |
UNGCPRO; |
UNGCPRO; |
7965 |
|
|
7966 |
/* Value is the image id. */ |
/* Value is the image id. */ |
7967 |
return img->id; |
return img->id; |
7968 |
} |
} |
8034 |
W32 support code |
W32 support code |
8035 |
***********************************************************************/ |
***********************************************************************/ |
8036 |
|
|
8037 |
|
/* Macro for defining functions that will be loaded from image DLLs. */ |
8038 |
|
#define DEF_IMGLIB_FN(func) FARPROC fn_##func |
8039 |
|
|
8040 |
|
/* Macro for loading those image functions from the library. */ |
8041 |
|
#define LOAD_IMGLIB_FN(lib,func) { \ |
8042 |
|
fn_##func = (void *) GetProcAddress (lib, #func); \ |
8043 |
|
if (!fn_##func) return 0; \ |
8044 |
|
} |
8045 |
|
|
8046 |
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, |
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int, |
8047 |
XImage **, Pixmap *)); |
XImage **, Pixmap *)); |
|
static void x_destroy_x_image P_ ((XImage *)); |
|
8048 |
static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); |
static void x_put_x_image P_ ((struct frame *, XImage *, Pixmap, int, int)); |
8049 |
|
|
8050 |
|
|
8107 |
header->biCompression = BI_RGB; |
header->biCompression = BI_RGB; |
8108 |
header->biClrUsed = palette_colors; |
header->biClrUsed = palette_colors; |
8109 |
|
|
8110 |
|
/* TODO: fill in palette. */ |
8111 |
|
if (depth == 1) |
8112 |
|
{ |
8113 |
|
(*ximg)->info.bmiColors[0].rgbBlue = 0; |
8114 |
|
(*ximg)->info.bmiColors[0].rgbGreen = 0; |
8115 |
|
(*ximg)->info.bmiColors[0].rgbRed = 0; |
8116 |
|
(*ximg)->info.bmiColors[0].rgbReserved = 0; |
8117 |
|
(*ximg)->info.bmiColors[1].rgbBlue = 255; |
8118 |
|
(*ximg)->info.bmiColors[1].rgbGreen = 255; |
8119 |
|
(*ximg)->info.bmiColors[1].rgbRed = 255; |
8120 |
|
(*ximg)->info.bmiColors[1].rgbReserved = 0; |
8121 |
|
} |
8122 |
|
|
8123 |
hdc = get_frame_dc (f); |
hdc = get_frame_dc (f); |
8124 |
|
|
8125 |
/* Create a DIBSection and raster array for the bitmap, |
/* Create a DIBSection and raster array for the bitmap, |
8126 |
and store its handle in *pixmap. */ |
and store its handle in *pixmap. */ |
8127 |
*pixmap = CreateDIBSection (hdc, &((*ximg)->info), DIB_RGB_COLORS, |
*pixmap = CreateDIBSection (hdc, &((*ximg)->info), |
8128 |
|
(depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS, |
8129 |
&((*ximg)->data), NULL, 0); |
&((*ximg)->data), NULL, 0); |
8130 |
|
|
8131 |
/* Realize display palette and garbage all frames. */ |
/* Realize display palette and garbage all frames. */ |
8170 |
struct frame *f; |
struct frame *f; |
8171 |
XImage *ximg; |
XImage *ximg; |
8172 |
Pixmap pixmap; |
Pixmap pixmap; |
8173 |
|
int width, height; |
8174 |
{ |
{ |
8175 |
|
#if 0 /* I don't think this is necessary looking at where it is used. */ |
8176 |
#if TODO /* W32 specific image code. */ |
HDC hdc = get_frame_dc (f); |
8177 |
GC gc; |
SetDIBits (hdc, pixmap, 0, height, ximg->data, &(ximg->info), DIB_RGB_COLORS); |
8178 |
|
release_frame_dc (f, hdc); |
|
xassert (interrupt_input_blocked); |
|
|
gc = XCreateGC (NULL, pixmap, 0, NULL); |
|
|
XPutImage (NULL, pixmap, gc, ximg, 0, 0, 0, 0, width, height); |
|
|
XFreeGC (NULL, gc); |
|
8179 |
#endif |
#endif |
8180 |
} |
} |
8181 |
|
|
8206 |
|
|
8207 |
/* Try to find FILE in data-directory, then x-bitmap-file-path. */ |
/* Try to find FILE in data-directory, then x-bitmap-file-path. */ |
8208 |
fd = openp (search_path, file, Qnil, &file_found, Qnil); |
fd = openp (search_path, file, Qnil, &file_found, Qnil); |
8209 |
|
|
8210 |
if (fd == -1) |
if (fd == -1) |
8211 |
file_found = Qnil; |
file_found = Qnil; |
8212 |
else |
else |
8231 |
struct stat st; |
struct stat st; |
8232 |
|
|
8233 |
if (stat (file, &st) == 0 |
if (stat (file, &st) == 0 |
8234 |
&& (fp = fopen (file, "r")) != NULL |
&& (fp = fopen (file, "rb")) != NULL |
8235 |
&& (buf = (char *) xmalloc (st.st_size), |
&& (buf = (char *) xmalloc (st.st_size), |
8236 |
fread (buf, 1, st.st_size, fp) == st.st_size)) |
fread (buf, 1, st.st_size, fp) == st.st_size)) |
8237 |
{ |
{ |
8248 |
buf = NULL; |
buf = NULL; |
8249 |
} |
} |
8250 |
} |
} |
8251 |
|
|
8252 |
return buf; |
return buf; |
8253 |
} |
} |
8254 |
|
|
8327 |
XBM_TK_NUMBER |
XBM_TK_NUMBER |
8328 |
}; |
}; |
8329 |
|
|
8330 |
|
|
8331 |
/* Return non-zero if OBJECT is a valid XBM-type image specification. |
/* Return non-zero if OBJECT is a valid XBM-type image specification. |
8332 |
A valid specification is a list starting with the symbol `image' |
A valid specification is a list starting with the symbol `image' |
8333 |
The rest of the list is a property list which must contain an |
The rest of the list is a property list which must contain an |
8362 |
Lisp_Object object; |
Lisp_Object object; |
8363 |
{ |
{ |
8364 |
struct image_keyword kw[XBM_LAST]; |
struct image_keyword kw[XBM_LAST]; |
8365 |
|
|
8366 |
bcopy (xbm_format, kw, sizeof kw); |
bcopy (xbm_format, kw, sizeof kw); |
8367 |
if (!parse_image_spec (object, kw, XBM_LAST, Qxbm)) |
if (!parse_image_spec (object, kw, XBM_LAST, Qxbm)) |
8368 |
return 0; |
return 0; |
8394 |
data = kw[XBM_DATA].value; |
data = kw[XBM_DATA].value; |
8395 |
width = XFASTINT (kw[XBM_WIDTH].value); |
width = XFASTINT (kw[XBM_WIDTH].value); |
8396 |
height = XFASTINT (kw[XBM_HEIGHT].value); |
height = XFASTINT (kw[XBM_HEIGHT].value); |
8397 |
|
|
8398 |
/* Check type of data, and width and height against contents of |
/* Check type of data, and width and height against contents of |
8399 |
data. */ |
data. */ |
8400 |
if (VECTORP (data)) |
if (VECTORP (data)) |
8401 |
{ |
{ |
8402 |
int i; |
int i; |
8403 |
|
|
8404 |
/* Number of elements of the vector must be >= height. */ |
/* Number of elements of the vector must be >= height. */ |
8405 |
if (XVECTOR (data)->size < height) |
if (XVECTOR (data)->size < height) |
8406 |
return 0; |
return 0; |
8413 |
|
|
8414 |
if (STRINGP (elt)) |
if (STRINGP (elt)) |
8415 |
{ |
{ |
8416 |
if (XSTRING (elt)->size |
if (SCHARS (elt) |
8417 |
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR) |
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR) |
8418 |
return 0; |
return 0; |
8419 |
} |
} |
8428 |
} |
} |
8429 |
else if (STRINGP (data)) |
else if (STRINGP (data)) |
8430 |
{ |
{ |
8431 |
if (XSTRING (data)->size |
if (SCHARS (data) |
8432 |
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height) |
< (width + BITS_PER_CHAR - 1) / BITS_PER_CHAR * height) |
8433 |
return 0; |
return 0; |
8434 |
} |
} |
8470 |
else if (isdigit (c)) |
else if (isdigit (c)) |
8471 |
{ |
{ |
8472 |
int value = 0, digit; |
int value = 0, digit; |
8473 |
|
|
8474 |
if (c == '0' && *s < end) |
if (c == '0' && *s < end) |
8475 |
{ |
{ |
8476 |
c = *(*s)++; |
c = *(*s)++; |
8564 |
|
|
8565 |
w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */ |
w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */ |
8566 |
w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */ |
w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */ |
8567 |
bits = (char *) xmalloc (height * w2); |
bits = (char *) alloca (height * w2); |
8568 |
bzero (bits, height * w2); |
bzero (bits, height * w2); |
8569 |
for (i = 0; i < height; i++) |
for (i = 0; i < height; i++) |
8570 |
{ |
{ |
8573 |
*p++ = reflect_byte(*data++); |
*p++ = reflect_byte(*data++); |
8574 |
} |
} |
8575 |
bmp = CreateBitmap (width, height, 1, 1, bits); |
bmp = CreateBitmap (width, height, 1, 1, bits); |
|
xfree (bits); |
|
8576 |
|
|
8577 |
return bmp; |
return bmp; |
8578 |
} |
} |
8607 |
if (LA1 != (TOKEN)) \ |
if (LA1 != (TOKEN)) \ |
8608 |
goto failure; \ |
goto failure; \ |
8609 |
else \ |
else \ |
8610 |
match () |
match () |
8611 |
|
|
8612 |
#define expect_ident(IDENT) \ |
#define expect_ident(IDENT) \ |
8613 |
if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ |
if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \ |
8650 |
{ |
{ |
8651 |
if (strcmp (buffer, "unsigned") == 0) |
if (strcmp (buffer, "unsigned") == 0) |
8652 |
{ |
{ |
8653 |
match (); |
match (); |
8654 |
expect_ident ("char"); |
expect_ident ("char"); |
8655 |
} |
} |
8656 |
else if (strcmp (buffer, "short") == 0) |
else if (strcmp (buffer, "short") == 0) |
8665 |
else |
else |
8666 |
goto failure; |
goto failure; |
8667 |
} |
} |
8668 |
else |
else |
8669 |
goto failure; |
goto failure; |
8670 |
|
|
8671 |
expect (XBM_TK_IDENT); |
expect (XBM_TK_IDENT); |
8685 |
int val = value; |
int val = value; |
8686 |
expect (XBM_TK_NUMBER); |
expect (XBM_TK_NUMBER); |
8687 |
|
|
8688 |
*p++ = val; |
*p++ = ~ val; |
8689 |
if (!padding_p || ((i + 2) % bytes_per_line)) |
if (!padding_p || ((i + 2) % bytes_per_line)) |
8690 |
*p++ = value >> 8; |
*p++ = ~ (value >> 8); |
8691 |
|
|
8692 |
if (LA1 == ',' || LA1 == '}') |
if (LA1 == ',' || LA1 == '}') |
8693 |
match (); |
match (); |
8694 |
else |
else |
8701 |
{ |
{ |
8702 |
int val = value; |
int val = value; |
8703 |
expect (XBM_TK_NUMBER); |
expect (XBM_TK_NUMBER); |
8704 |
|
|
8705 |
*p++ = val; |
*p++ = ~ val; |
8706 |
|
|
8707 |
if (LA1 == ',' || LA1 == '}') |
if (LA1 == ',' || LA1 == '}') |
8708 |
match (); |
match (); |
8728 |
#undef expect_ident |
#undef expect_ident |
8729 |
} |
} |
8730 |
|
|
8731 |
|
static void convert_mono_to_color_image (f, img, foreground, background) |
8732 |
|
struct frame *f; |
8733 |
|
struct image *img; |
8734 |
|
COLORREF foreground, background; |
8735 |
|
{ |
8736 |
|
HDC hdc, old_img_dc, new_img_dc; |
8737 |
|
HGDIOBJ old_prev, new_prev; |
8738 |
|
HBITMAP new_pixmap; |
8739 |
|
|
8740 |
|
hdc = get_frame_dc (f); |
8741 |
|
old_img_dc = CreateCompatibleDC (hdc); |
8742 |
|
new_img_dc = CreateCompatibleDC (hdc); |
8743 |
|
new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height); |
8744 |
|
release_frame_dc (f, hdc); |
8745 |
|
old_prev = SelectObject (old_img_dc, img->pixmap); |
8746 |
|
new_prev = SelectObject (new_img_dc, new_pixmap); |
8747 |
|
SetTextColor (new_img_dc, foreground); |
8748 |
|
SetBkColor (new_img_dc, background); |
8749 |
|
|
8750 |
|
BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc, |
8751 |
|
0, 0, SRCCOPY); |
8752 |
|
|
8753 |
|
SelectObject (old_img_dc, old_prev); |
8754 |
|
SelectObject (new_img_dc, new_prev); |
8755 |
|
DeleteDC (old_img_dc); |
8756 |
|
DeleteDC (new_img_dc); |
8757 |
|
DeleteObject (img->pixmap); |
8758 |
|
if (new_pixmap == 0) |
8759 |
|
fprintf (stderr, "Failed to convert image to color.\n"); |
8760 |
|
else |
8761 |
|
img->pixmap = new_pixmap; |
8762 |
|
} |
8763 |
|
|
8764 |
/* Load XBM image IMG which will be displayed on frame F from buffer |
/* Load XBM image IMG which will be displayed on frame F from buffer |
8765 |
CONTENTS. END is the end of the buffer. Value is non-zero if |
CONTENTS. END is the end of the buffer. Value is non-zero if |
8774 |
int rc; |
int rc; |
8775 |
unsigned char *data; |
unsigned char *data; |
8776 |
int success_p = 0; |
int success_p = 0; |
8777 |
|
|
8778 |
rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); |
rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); |
8779 |
if (rc) |
if (rc) |
8780 |
{ |
{ |
8781 |
unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); |
unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); |
8782 |
unsigned long background = FRAME_BACKGROUND_PIXEL (f); |
unsigned long background = FRAME_BACKGROUND_PIXEL (f); |
8783 |
|
int non_default_colors = 0; |
8784 |
Lisp_Object value; |
Lisp_Object value; |
8785 |
|
|
8786 |
xassert (img->width > 0 && img->height > 0); |
xassert (img->width > 0 && img->height > 0); |
8787 |
|
|
8788 |
/* Get foreground and background colors, maybe allocate colors. */ |
/* Get foreground and background colors, maybe allocate colors. */ |
8789 |
value = image_spec_value (img->spec, QCforeground, NULL); |
value = image_spec_value (img->spec, QCforeground, NULL); |
8790 |
if (!NILP (value)) |
if (!NILP (value)) |
8791 |
foreground = x_alloc_image_color (f, img, value, foreground); |
{ |
8792 |
|
foreground = x_alloc_image_color (f, img, value, foreground); |
8793 |
|
non_default_colors = 1; |
8794 |
|
} |
8795 |
value = image_spec_value (img->spec, QCbackground, NULL); |
value = image_spec_value (img->spec, QCbackground, NULL); |
8796 |
if (!NILP (value)) |
if (!NILP (value)) |
8797 |
{ |
{ |
8798 |
background = x_alloc_image_color (f, img, value, background); |
background = x_alloc_image_color (f, img, value, background); |
8799 |
img->background = background; |
img->background = background; |
8800 |
img->background_valid = 1; |
img->background_valid = 1; |
8801 |
|
non_default_colors = 1; |
8802 |
} |
} |
8803 |
img->pixmap |
img->pixmap |
8804 |
= w32_create_pixmap_from_bitmap_data (img->width, img->height, data); |
= w32_create_pixmap_from_bitmap_data (img->width, img->height, data); |
8805 |
|
|
8806 |
|
/* If colors were specified, transfer the bitmap to a color one. */ |
8807 |
|
if (non_default_colors) |
8808 |
|
convert_mono_to_color_image (f, img, foreground, background); |
8809 |
|
|
8810 |
xfree (data); |
xfree (data); |
8811 |
|
|
8812 |
if (img->pixmap == 0) |
if (img->pixmap == 0) |
8832 |
{ |
{ |
8833 |
int w, h; |
int w, h; |
8834 |
return (STRINGP (data) |
return (STRINGP (data) |
8835 |
&& xbm_read_bitmap_data (XSTRING (data)->data, |
&& xbm_read_bitmap_data (SDATA (data), |
8836 |
(XSTRING (data)->data |
(SDATA (data) |
8837 |
+ STRING_BYTES (XSTRING (data))), |
+ SBYTES (data)), |
8838 |
&w, &h, NULL)); |
&w, &h, NULL)); |
8839 |
} |
} |
8840 |
|
|
8841 |
|
|
8842 |
/* Fill image IMG which is used on frame F with pixmap data. Value is |
/* Fill image IMG which is used on frame F with pixmap data. Value is |
8843 |
non-zero if successful. */ |
non-zero if successful. */ |
8844 |
|
|
8870 |
return 0; |
return 0; |
8871 |
} |
} |
8872 |
|
|
8873 |
contents = slurp_file (XSTRING (file)->data, &size); |
contents = slurp_file (SDATA (file), &size); |
8874 |
if (contents == NULL) |
if (contents == NULL) |
8875 |
{ |
{ |
8876 |
image_error ("Error loading XBM image `%s'", img->spec, Qnil); |
image_error ("Error loading XBM image `%s'", img->spec, Qnil); |
8885 |
{ |
{ |
8886 |
struct image_keyword fmt[XBM_LAST]; |
struct image_keyword fmt[XBM_LAST]; |
8887 |
Lisp_Object data; |
Lisp_Object data; |
|
int depth; |
|
8888 |
unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); |
unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); |
8889 |
unsigned long background = FRAME_BACKGROUND_PIXEL (f); |
unsigned long background = FRAME_BACKGROUND_PIXEL (f); |
8890 |
|
int non_default_colors = 0; |
8891 |
char *bits; |
char *bits; |
8892 |
int parsed_p; |
int parsed_p; |
8893 |
int in_memory_file_p = 0; |
int in_memory_file_p = 0; |
8912 |
/* Get foreground and background colors, maybe allocate colors. */ |
/* Get foreground and background colors, maybe allocate colors. */ |
8913 |
if (fmt[XBM_FOREGROUND].count |
if (fmt[XBM_FOREGROUND].count |
8914 |
&& STRINGP (fmt[XBM_FOREGROUND].value)) |
&& STRINGP (fmt[XBM_FOREGROUND].value)) |
8915 |
foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, |
{ |
8916 |
foreground); |
foreground = x_alloc_image_color (f, img, fmt[XBM_FOREGROUND].value, |
8917 |
|
foreground); |
8918 |
|
non_default_colors = 1; |
8919 |
|
} |
8920 |
|
|
8921 |
if (fmt[XBM_BACKGROUND].count |
if (fmt[XBM_BACKGROUND].count |
8922 |
&& STRINGP (fmt[XBM_BACKGROUND].value)) |
&& STRINGP (fmt[XBM_BACKGROUND].value)) |
8923 |
background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, |
{ |
8924 |
background); |
background = x_alloc_image_color (f, img, fmt[XBM_BACKGROUND].value, |
8925 |
|
background); |
8926 |
|
non_default_colors = 1; |
8927 |
|
} |
8928 |
|
|
8929 |
if (in_memory_file_p) |
if (in_memory_file_p) |
8930 |
success_p = xbm_load_image (f, img, XSTRING (data)->data, |
success_p = xbm_load_image (f, img, SDATA (data), |
8931 |
(XSTRING (data)->data |
(SDATA (data) |
8932 |
+ STRING_BYTES (XSTRING (data)))); |
+ SBYTES (data))); |
8933 |
else |
else |
8934 |
{ |
{ |
8935 |
if (VECTORP (data)) |
if (VECTORP (data)) |
8937 |
int i; |
int i; |
8938 |
char *p; |
char *p; |
8939 |
int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; |
int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR; |
8940 |
|
|
8941 |
p = bits = (char *) alloca (nbytes * img->height); |
p = bits = (char *) alloca (nbytes * img->height); |
8942 |
for (i = 0; i < img->height; ++i, p += nbytes) |
for (i = 0; i < img->height; ++i, p += nbytes) |
8943 |
{ |
{ |
8944 |
Lisp_Object line = XVECTOR (data)->contents[i]; |
Lisp_Object line = XVECTOR (data)->contents[i]; |
8945 |
if (STRINGP (line)) |
if (STRINGP (line)) |
8946 |
bcopy (XSTRING (line)->data, p, nbytes); |
bcopy (SDATA (line), p, nbytes); |
8947 |
else |
else |
8948 |
bcopy (XBOOL_VECTOR (line)->data, p, nbytes); |
bcopy (XBOOL_VECTOR (line)->data, p, nbytes); |
8949 |
} |
} |
8950 |
} |
} |
8951 |
else if (STRINGP (data)) |
else if (STRINGP (data)) |
8952 |
bits = XSTRING (data)->data; |
bits = SDATA (data); |
8953 |
else |
else |
8954 |
bits = XBOOL_VECTOR (data)->data; |
bits = XBOOL_VECTOR (data)->data; |
8955 |
|
|
8956 |
/* Create the pixmap. */ |
/* Create the pixmap. */ |
|
depth = one_w32_display_info.n_cbits; |
|
8957 |
img->pixmap |
img->pixmap |
8958 |
= w32_create_pixmap_from_bitmap_data (img->width, img->height, |
= w32_create_pixmap_from_bitmap_data (img->width, img->height, |
8959 |
bits); |
bits); |
8960 |
|
|
8961 |
|
/* If colors were specified, transfer the bitmap to a color one. */ |
8962 |
|
if (non_default_colors) |
8963 |
|
convert_mono_to_color_image (f, img, foreground, background); |
8964 |
|
|
8965 |
if (img->pixmap) |
if (img->pixmap) |
8966 |
success_p = 1; |
success_p = 1; |
8967 |
else |
else |
8975 |
|
|
8976 |
return success_p; |
return success_p; |
8977 |
} |
} |
8978 |
|
|
8979 |
|
|
8980 |
|
|
8981 |
/*********************************************************************** |
/*********************************************************************** |
8982 |
XPM images |
XPM images |
8983 |
***********************************************************************/ |
***********************************************************************/ |
8984 |
|
|
8985 |
#if HAVE_XPM |
#if HAVE_XPM |
8986 |
|
|
8987 |
static int xpm_image_p P_ ((Lisp_Object object)); |
static int xpm_image_p P_ ((Lisp_Object object)); |
8988 |
static int xpm_load P_ ((struct frame *f, struct image *img)); |
static int xpm_load P_ ((struct frame *f, struct image *img)); |
8989 |
static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); |
static int xpm_valid_color_symbols_p P_ ((Lisp_Object)); |
8990 |
|
|
8991 |
|
/* Indicate to xpm.h that we don't have Xlib. */ |
8992 |
|
#define FOR_MSW |
8993 |
|
/* simx.h in xpm defines XColor and XImage differently than Emacs. */ |
8994 |
|
#define XColor xpm_XColor |
8995 |
|
#define XImage xpm_XImage |
8996 |
|
#define PIXEL_ALREADY_TYPEDEFED |
8997 |
#include "X11/xpm.h" |
#include "X11/xpm.h" |
8998 |
|
#undef FOR_MSW |
8999 |
|
#undef XColor |
9000 |
|
#undef XImage |
9001 |
|
#undef PIXEL_ALREADY_TYPEDEFED |
9002 |
|
|
9003 |
/* The symbol `xpm' identifying XPM-format images. */ |
/* The symbol `xpm' identifying XPM-format images. */ |
9004 |
|
|
9030 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
9031 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
9032 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
9033 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
9034 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
9035 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
9036 |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
9040 |
{":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
{":background", IMAGE_STRING_OR_NIL_VALUE, 0} |
9041 |
}; |
}; |
9042 |
|
|
9043 |
/* Structure describing the image type XBM. */ |
/* Structure describing the image type XPM. */ |
9044 |
|
|
9045 |
static struct image_type xpm_type = |
static struct image_type xpm_type = |
9046 |
{ |
{ |
9052 |
}; |
}; |
9053 |
|
|
9054 |
|
|
9055 |
|
/* XPM library details. */ |
9056 |
|
|
9057 |
|
DEF_IMGLIB_FN (XpmFreeAttributes); |
9058 |
|
DEF_IMGLIB_FN (XpmCreateImageFromBuffer); |
9059 |
|
DEF_IMGLIB_FN (XpmReadFileToImage); |
9060 |
|
DEF_IMGLIB_FN (XImageFree); |
9061 |
|
|
9062 |
|
|
9063 |
|
static int |
9064 |
|
init_xpm_functions (library) |
9065 |
|
HMODULE library; |
9066 |
|
{ |
9067 |
|
LOAD_IMGLIB_FN (library, XpmFreeAttributes); |
9068 |
|
LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer); |
9069 |
|
LOAD_IMGLIB_FN (library, XpmReadFileToImage); |
9070 |
|
LOAD_IMGLIB_FN (library, XImageFree); |
9071 |
|
|
9072 |
|
return 1; |
9073 |
|
} |
9074 |
|
|
9075 |
/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list |
/* Value is non-zero if COLOR_SYMBOLS is a valid color symbols list |
9076 |
for XPM images. Such a list must consist of conses whose car and |
for XPM images. Such a list must consist of conses whose car and |
9077 |
cdr are strings. */ |
cdr are strings. */ |
9108 |
/* Either no `:color-symbols' or it's a list of conses |
/* Either no `:color-symbols' or it's a list of conses |
9109 |
whose car and cdr are strings. */ |
whose car and cdr are strings. */ |
9110 |
&& (fmt[XPM_COLOR_SYMBOLS].count == 0 |
&& (fmt[XPM_COLOR_SYMBOLS].count == 0 |
9111 |
|| xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)) |
|| xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value))); |
|
&& (fmt[XPM_ASCENT].count == 0 |
|
|
|| XFASTINT (fmt[XPM_ASCENT].value) < 100)); |
|
9112 |
} |
} |
9113 |
|
|
9114 |
|
|
9120 |
struct frame *f; |
struct frame *f; |
9121 |
struct image *img; |
struct image *img; |
9122 |
{ |
{ |
9123 |
int rc, i; |
HDC hdc; |
9124 |
|
int rc; |
9125 |
XpmAttributes attrs; |
XpmAttributes attrs; |
9126 |
Lisp_Object specified_file, color_symbols; |
Lisp_Object specified_file, color_symbols; |
9127 |
|
xpm_XImage * xpm_image, * xpm_mask; |
9128 |
|
|
9129 |
/* Configure the XPM lib. Use the visual of frame F. Allocate |
/* Configure the XPM lib. Use the visual of frame F. Allocate |
9130 |
close colors. Return colors allocated. */ |
close colors. Return colors allocated. */ |
9131 |
bzero (&attrs, sizeof attrs); |
bzero (&attrs, sizeof attrs); |
9132 |
|
xpm_image = xpm_mask = NULL; |
9133 |
|
|
9134 |
|
#if 0 |
9135 |
attrs.visual = FRAME_X_VISUAL (f); |
attrs.visual = FRAME_X_VISUAL (f); |
9136 |
attrs.colormap = FRAME_X_COLORMAP (f); |
attrs.colormap = FRAME_X_COLORMAP (f); |
9137 |
attrs.valuemask |= XpmVisual; |
attrs.valuemask |= XpmVisual; |
9138 |
attrs.valuemask |= XpmColormap; |
attrs.valuemask |= XpmColormap; |
9139 |
|
#endif |
9140 |
attrs.valuemask |= XpmReturnAllocPixels; |
attrs.valuemask |= XpmReturnAllocPixels; |
9141 |
#ifdef XpmAllocCloseColors |
#ifdef XpmAllocCloseColors |
9142 |
attrs.alloc_close_colors = 1; |
attrs.alloc_close_colors = 1; |
9154 |
Lisp_Object tail; |
Lisp_Object tail; |
9155 |
XpmColorSymbol *xpm_syms; |
XpmColorSymbol *xpm_syms; |
9156 |
int i, size; |
int i, size; |
9157 |
|
|
9158 |
attrs.valuemask |= XpmColorSymbols; |
attrs.valuemask |= XpmColorSymbols; |
9159 |
|
|
9160 |
/* Count number of symbols. */ |
/* Count number of symbols. */ |
9175 |
{ |
{ |
9176 |
Lisp_Object name = XCAR (XCAR (tail)); |
Lisp_Object name = XCAR (XCAR (tail)); |
9177 |
Lisp_Object color = XCDR (XCAR (tail)); |
Lisp_Object color = XCDR (XCAR (tail)); |
9178 |
xpm_syms[i].name = (char *) alloca (XSTRING (name)->size + 1); |
xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1); |
9179 |
strcpy (xpm_syms[i].name, XSTRING (name)->data); |
strcpy (xpm_syms[i].name, SDATA (name)); |
9180 |
xpm_syms[i].value = (char *) alloca (XSTRING (color)->size + 1); |
xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1); |
9181 |
strcpy (xpm_syms[i].value, XSTRING (color)->data); |
strcpy (xpm_syms[i].value, SDATA (color)); |
9182 |
} |
} |
9183 |
} |
} |
9184 |
|
|
9185 |
/* Create a pixmap for the image, either from a file, or from a |
/* Create a pixmap for the image, either from a file, or from a |
9186 |
string buffer containing data in the same format as an XPM file. */ |
string buffer containing data in the same format as an XPM file. */ |
9187 |
BLOCK_INPUT; |
|
9188 |
specified_file = image_spec_value (img->spec, QCfile, NULL); |
specified_file = image_spec_value (img->spec, QCfile, NULL); |
9189 |
|
|
9190 |
|
{ |
9191 |
|
HDC frame_dc = get_frame_dc (f); |
9192 |
|
hdc = CreateCompatibleDC (frame_dc); |
9193 |
|
release_frame_dc (f, frame_dc); |
9194 |
|
} |
9195 |
|
|
9196 |
if (STRINGP (specified_file)) |
if (STRINGP (specified_file)) |
9197 |
{ |
{ |
9198 |
Lisp_Object file = x_find_image_file (specified_file); |
Lisp_Object file = x_find_image_file (specified_file); |
9199 |
if (!STRINGP (file)) |
if (!STRINGP (file)) |
9200 |
{ |
{ |
9201 |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
|
UNBLOCK_INPUT; |
|
9202 |
return 0; |
return 0; |
9203 |
} |
} |
9204 |
|
|
9205 |
rc = XpmReadFileToPixmap (NULL, FRAME_W32_WINDOW (f), |
/* XpmReadFileToPixmap is not available in the Windows port of |
9206 |
XSTRING (file)->data, &img->pixmap, &img->mask, |
libxpm. But XpmReadFileToImage almost does what we want. */ |
9207 |
&attrs); |
rc = fn_XpmReadFileToImage (&hdc, SDATA (file), |
9208 |
|
&xpm_image, &xpm_mask, |
9209 |
|
&attrs); |
9210 |
} |
} |
9211 |
else |
else |
9212 |
{ |
{ |
9213 |
Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); |
Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL); |
9214 |
rc = XpmCreatePixmapFromBuffer (NULL, FRAME_W32_WINDOW (f), |
/* XpmCreatePixmapFromBuffer is not available in the Windows port |
9215 |
XSTRING (buffer)->data, |
of libxpm. But XpmCreateImageFromBuffer almost does what we want. */ |
9216 |
&img->pixmap, &img->mask, |
rc = fn_XpmCreateImageFromBuffer (&hdc, SDATA (buffer), |
9217 |
&attrs); |
&xpm_image, &xpm_mask, |
9218 |
|
&attrs); |
9219 |
} |
} |
|
UNBLOCK_INPUT; |
|
9220 |
|
|
9221 |
if (rc == XpmSuccess) |
if (rc == XpmSuccess) |
9222 |
{ |
{ |
9223 |
|
int i; |
9224 |
|
|
9225 |
|
/* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap, |
9226 |
|
plus some duplicate attributes. */ |
9227 |
|
if (xpm_image && xpm_image->bitmap) |
9228 |
|
{ |
9229 |
|
img->pixmap = xpm_image->bitmap; |
9230 |
|
/* XImageFree in libXpm frees XImage struct without destroying |
9231 |
|
the bitmap, which is what we want. */ |
9232 |
|
fn_XImageFree (xpm_image); |
9233 |
|
} |
9234 |
|
if (xpm_mask && xpm_mask->bitmap) |
9235 |
|
{ |
9236 |
|
/* The mask appears to be inverted compared with what we expect. |
9237 |
|
TODO: invert our expectations. See other places where we |
9238 |
|
have to invert bits because our idea of masks is backwards. */ |
9239 |
|
HGDIOBJ old_obj; |
9240 |
|
old_obj = SelectObject (hdc, xpm_mask->bitmap); |
9241 |
|
|
9242 |
|
PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT); |
9243 |
|
SelectObject (hdc, old_obj); |
9244 |
|
|
9245 |
|
img->mask = xpm_mask->bitmap; |
9246 |
|
fn_XImageFree (xpm_mask); |
9247 |
|
DeleteDC (hdc); |
9248 |
|
} |
9249 |
|
|
9250 |
|
DeleteDC (hdc); |
9251 |
|
|
9252 |
/* Remember allocated colors. */ |
/* Remember allocated colors. */ |
9253 |
img->ncolors = attrs.nalloc_pixels; |
img->ncolors = attrs.nalloc_pixels; |
9254 |
img->colors = (unsigned long *) xmalloc (img->ncolors |
img->colors = (unsigned long *) xmalloc (img->ncolors |
9261 |
xassert (img->width > 0 && img->height > 0); |
xassert (img->width > 0 && img->height > 0); |
9262 |
|
|
9263 |
/* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */ |
/* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */ |
9264 |
BLOCK_INPUT; |
fn_XpmFreeAttributes (&attrs); |
|
XpmFreeAttributes (&attrs); |
|
|
UNBLOCK_INPUT; |
|
9265 |
} |
} |
9266 |
else |
else |
9267 |
{ |
{ |
9268 |
|
DeleteDC (hdc); |
9269 |
|
|
9270 |
switch (rc) |
switch (rc) |
9271 |
{ |
{ |
9272 |
case XpmOpenFailed: |
case XpmOpenFailed: |
9273 |
image_error ("Error opening XPM file (%s)", img->spec, Qnil); |
image_error ("Error opening XPM file (%s)", img->spec, Qnil); |
9274 |
break; |
break; |
9275 |
|
|
9276 |
case XpmFileInvalid: |
case XpmFileInvalid: |
9277 |
image_error ("Invalid XPM file (%s)", img->spec, Qnil); |
image_error ("Invalid XPM file (%s)", img->spec, Qnil); |
9278 |
break; |
break; |
9279 |
|
|
9280 |
case XpmNoMemory: |
case XpmNoMemory: |
9281 |
image_error ("Out of memory (%s)", img->spec, Qnil); |
image_error ("Out of memory (%s)", img->spec, Qnil); |
9282 |
break; |
break; |
9283 |
|
|
9284 |
case XpmColorFailed: |
case XpmColorFailed: |
9285 |
image_error ("Color allocation error (%s)", img->spec, Qnil); |
image_error ("Color allocation error (%s)", img->spec, Qnil); |
9286 |
break; |
break; |
9287 |
|
|
9288 |
default: |
default: |
9289 |
image_error ("Unknown error (%s)", img->spec, Qnil); |
image_error ("Unknown error (%s)", img->spec, Qnil); |
9290 |
break; |
break; |
9433 |
int rc; |
int rc; |
9434 |
|
|
9435 |
BLOCK_INPUT; |
BLOCK_INPUT; |
9436 |
|
|
9437 |
cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); |
cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f)); |
9438 |
color.pixel = pixel; |
color.pixel = pixel; |
9439 |
XQueryColor (NULL, cmap, &color); |
XQueryColor (NULL, cmap, &color); |
9443 |
if (rc) |
if (rc) |
9444 |
{ |
{ |
9445 |
++ct_colors_allocated; |
++ct_colors_allocated; |
9446 |
|
|
9447 |
p = (struct ct_color *) xmalloc (sizeof *p); |
p = (struct ct_color *) xmalloc (sizeof *p); |
9448 |
p->r = color.red; |
p->r = color.red; |
9449 |
p->g = color.green; |
p->g = color.green; |
9480 |
colors = (unsigned long *) xmalloc (ct_colors_allocated |
colors = (unsigned long *) xmalloc (ct_colors_allocated |
9481 |
* sizeof *colors); |
* sizeof *colors); |
9482 |
*n = ct_colors_allocated; |
*n = ct_colors_allocated; |
9483 |
|
|
9484 |
for (i = j = 0; i < CT_SIZE; ++i) |
for (i = j = 0; i < CT_SIZE; ++i) |
9485 |
for (p = ct_table[i]; p; p = p->next) |
for (p = ct_table[i]; p; p = p->next) |
9486 |
colors[j++] = p->pixel; |
colors[j++] = p->pixel; |
9542 |
{ |
{ |
9543 |
int x, y; |
int x, y; |
9544 |
XColor *colors, *p; |
XColor *colors, *p; |
9545 |
XImage *ximg; |
HDC hdc, bmpdc; |
9546 |
|
HGDIOBJ prev; |
9547 |
|
|
9548 |
colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); |
colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); |
9549 |
#if 0 /* TODO: implement image colors. */ |
|
9550 |
/* Get the X image IMG->pixmap. */ |
/* Load the image into a memory device context. */ |
9551 |
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap, |
hdc = get_frame_dc (f); |
9552 |
0, 0, img->width, img->height, ~0, ZPixmap); |
bmpdc = CreateCompatibleDC (hdc); |
9553 |
|
release_frame_dc (f, hdc); |
9554 |
|
prev = SelectObject (bmpdc, img->pixmap); |
9555 |
|
|
9556 |
/* Fill the `pixel' members of the XColor array. I wished there |
/* Fill the `pixel' members of the XColor array. I wished there |
9557 |
were an easy and portable way to circumvent XGetPixel. */ |
were an easy and portable way to circumvent XGetPixel. */ |
9559 |
for (y = 0; y < img->height; ++y) |
for (y = 0; y < img->height; ++y) |
9560 |
{ |
{ |
9561 |
XColor *row = p; |
XColor *row = p; |
9562 |
|
|
9563 |
for (x = 0; x < img->width; ++x, ++p) |
for (x = 0; x < img->width; ++x, ++p) |
9564 |
p->pixel = XGetPixel (ximg, x, y); |
{ |
9565 |
|
/* TODO: palette support needed here? */ |
9566 |
|
p->pixel = GetPixel (bmpdc, x, y); |
9567 |
|
|
9568 |
if (rgb_p) |
if (rgb_p) |
9569 |
x_query_colors (f, row, img->width); |
{ |
9570 |
|
p->red = 256 * GetRValue (p->pixel); |
9571 |
|
p->green = 256 * GetGValue (p->pixel); |
9572 |
|
p->blue = 256 * GetBValue (p->pixel); |
9573 |
|
} |
9574 |
|
} |
9575 |
} |
} |
9576 |
|
|
9577 |
XDestroyImage (ximg); |
SelectObject (bmpdc, prev); |
9578 |
#endif |
DeleteDC (bmpdc); |
9579 |
|
|
9580 |
return colors; |
return colors; |
9581 |
} |
} |
9582 |
|
|
9591 |
{ |
{ |
9592 |
int width = ximg->info.bmiHeader.biWidth; |
int width = ximg->info.bmiHeader.biWidth; |
9593 |
int height = ximg->info.bmiHeader.biHeight; |
int height = ximg->info.bmiHeader.biHeight; |
|
int rowbytes = width * 3; |
|
9594 |
unsigned char * pixel; |
unsigned char * pixel; |
9595 |
|
|
9596 |
/* Don't support putting pixels in images with palettes. */ |
/* True color images. */ |
9597 |
xassert (ximg->info.bmiHeader.biBitCount == 24); |
if (ximg->info.bmiHeader.biBitCount == 24) |
9598 |
|
{ |
9599 |
/* Ensure scanlines are aligned on 4 byte boundaries. */ |
int rowbytes = width * 3; |
9600 |
if (rowbytes % 4) |
/* Ensure scanlines are aligned on 4 byte boundaries. */ |
9601 |
rowbytes += 4 - (rowbytes % 4); |
if (rowbytes % 4) |
9602 |
|
rowbytes += 4 - (rowbytes % 4); |
9603 |
pixel = ximg->data + y * rowbytes + x * 3; |
|
9604 |
*pixel = 255 - GetRValue (color); |
pixel = ximg->data + y * rowbytes + x * 3; |
9605 |
*(pixel + 1) = 255 - GetGValue (color); |
/* Windows bitmaps are in BGR order. */ |
9606 |
*(pixel + 2) = 255 - GetBValue (color); |
*pixel = GetBValue (color); |
9607 |
|
*(pixel + 1) = GetGValue (color); |
9608 |
|
*(pixel + 2) = GetRValue (color); |
9609 |
|
} |
9610 |
|
/* Monochrome images. */ |
9611 |
|
else if (ximg->info.bmiHeader.biBitCount == 1) |
9612 |
|
{ |
9613 |
|
int rowbytes = width / 8; |
9614 |
|
/* Ensure scanlines are aligned on 4 byte boundaries. */ |
9615 |
|
if (rowbytes % 4) |
9616 |
|
rowbytes += 4 - (rowbytes % 4); |
9617 |
|
pixel = ximg->data + y * rowbytes + x / 8; |
9618 |
|
/* Filter out palette info. */ |
9619 |
|
if (color & 0x00ffffff) |
9620 |
|
*pixel = *pixel | (1 << x % 8); |
9621 |
|
else |
9622 |
|
*pixel = *pixel & ~(1 << x % 8); |
9623 |
|
} |
9624 |
|
else |
9625 |
|
image_error ("XPutPixel: palette image not supported.", Qnil, Qnil); |
9626 |
} |
} |
9627 |
|
|
|
|
|
9628 |
/* Create IMG->pixmap from an array COLORS of XColor structures, whose |
/* Create IMG->pixmap from an array COLORS of XColor structures, whose |
9629 |
RGB members are set. F is the frame on which this all happens. |
RGB members are set. F is the frame on which this all happens. |
9630 |
COLORS will be freed; an existing IMG->pixmap will be freed, too. */ |
COLORS will be freed; an existing IMG->pixmap will be freed, too. */ |
9652 |
#if 0 /* TODO: color tables. */ |
#if 0 /* TODO: color tables. */ |
9653 |
pixel = lookup_rgb_color (f, p->red, p->green, p->blue); |
pixel = lookup_rgb_color (f, p->red, p->green, p->blue); |
9654 |
#else |
#else |
9655 |
pixel = PALETTERGB (p->red, p->green, p->blue); |
pixel = PALETTERGB (p->red / 256, p->green / 256, p->blue / 256); |
9656 |
#endif |
#endif |
9657 |
XPutPixel (oimg, x, y, pixel); |
XPutPixel (oimg, x, y, pixel); |
9658 |
} |
} |
9674 |
|
|
9675 |
MATRIX is a nine-element array specifying the transformation |
MATRIX is a nine-element array specifying the transformation |
9676 |
matrix. See emboss_matrix for an example. |
matrix. See emboss_matrix for an example. |
9677 |
|
|
9678 |
COLOR_ADJUST is a color adjustment added to each pixel of the |
COLOR_ADJUST is a color adjustment added to each pixel of the |
9679 |
outgoing image. */ |
outgoing image. */ |
9680 |
|
|
9702 |
p = COLOR (new, img->width - 1, y); |
p = COLOR (new, img->width - 1, y); |
9703 |
p->red = p->green = p->blue = 0xffff/2; |
p->red = p->green = p->blue = 0xffff/2; |
9704 |
} |
} |
9705 |
|
|
9706 |
for (x = 1; x < img->width - 1; ++x) |
for (x = 1; x < img->width - 1; ++x) |
9707 |
{ |
{ |
9708 |
p = COLOR (new, x, 0); |
p = COLOR (new, x, 0); |
9714 |
for (y = 1; y < img->height - 1; ++y) |
for (y = 1; y < img->height - 1; ++y) |
9715 |
{ |
{ |
9716 |
p = COLOR (new, 1, y); |
p = COLOR (new, 1, y); |
9717 |
|
|
9718 |
for (x = 1; x < img->width - 1; ++x, ++p) |
for (x = 1; x < img->width - 1; ++x, ++p) |
9719 |
{ |
{ |
9720 |
int r, g, b, y1, x1; |
int r, g, b, y1, x1; |
9788 |
{ |
{ |
9789 |
int i = 0; |
int i = 0; |
9790 |
int trans[9]; |
int trans[9]; |
9791 |
|
|
9792 |
if (CONSP (matrix)) |
if (CONSP (matrix)) |
9793 |
{ |
{ |
9794 |
for (i = 0; |
for (i = 0; |
9845 |
should. */ |
should. */ |
9846 |
if (dpyinfo->n_planes * dpyinfo->n_cbits < 2 || cross_disabled_images) |
if (dpyinfo->n_planes * dpyinfo->n_cbits < 2 || cross_disabled_images) |
9847 |
{ |
{ |
9848 |
#if 0 /* TODO: full image support */ |
HDC hdc, bmpdc; |
9849 |
Display *dpy = FRAME_X_DISPLAY (f); |
HGDIOBJ prev; |
9850 |
GC gc; |
|
9851 |
|
hdc = get_frame_dc (f); |
9852 |
gc = XCreateGC (dpy, img->pixmap, 0, NULL); |
bmpdc = CreateCompatibleDC (hdc); |
9853 |
XSetForeground (dpy, gc, BLACK_PIX_DEFAULT (f)); |
release_frame_dc (f, hdc); |
9854 |
XDrawLine (dpy, img->pixmap, gc, 0, 0, |
|
9855 |
img->width - 1, img->height - 1); |
prev = SelectObject (bmpdc, img->pixmap); |
9856 |
XDrawLine (dpy, img->pixmap, gc, 0, img->height - 1, |
|
9857 |
img->width - 1, 0); |
SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f)); |
9858 |
XFreeGC (dpy, gc); |
MoveToEx (bmpdc, 0, 0, NULL); |
9859 |
|
LineTo (bmpdc, img->width - 1, img->height - 1); |
9860 |
|
MoveToEx (bmpdc, 0, img->height - 1, NULL); |
9861 |
|
LineTo (bmpdc, img->width - 1, 0); |
9862 |
|
|
9863 |
if (img->mask) |
if (img->mask) |
9864 |
{ |
{ |
9865 |
gc = XCreateGC (dpy, img->mask, 0, NULL); |
SelectObject (bmpdc, img->mask); |
9866 |
XSetForeground (dpy, gc, WHITE_PIX_DEFAULT (f)); |
SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f)); |
9867 |
XDrawLine (dpy, img->mask, gc, 0, 0, |
MoveToEx (bmpdc, 0, 0, NULL); |
9868 |
img->width - 1, img->height - 1); |
LineTo (bmpdc, img->width - 1, img->height - 1); |
9869 |
XDrawLine (dpy, img->mask, gc, 0, img->height - 1, |
MoveToEx (bmpdc, 0, img->height - 1, NULL); |
9870 |
img->width - 1, 0); |
LineTo (bmpdc, img->width - 1, 0); |
|
XFreeGC (dpy, gc); |
|
9871 |
} |
} |
9872 |
#endif |
SelectObject (bmpdc, prev); |
9873 |
|
DeleteDC (bmpdc); |
9874 |
} |
} |
9875 |
} |
} |
9876 |
|
|
9888 |
struct image *img; |
struct image *img; |
9889 |
Lisp_Object how; |
Lisp_Object how; |
9890 |
{ |
{ |
9891 |
#if 0 /* TODO: full image support. */ |
HDC img_dc, frame_dc; |
9892 |
Display *dpy = FRAME_W32_DISPLAY (f); |
HGDIOBJ prev; |
9893 |
XImage *ximg, *mask_img; |
char *mask_img; |
9894 |
int x, y, rc, use_img_background; |
int x, y, rc, use_img_background; |
9895 |
unsigned long bg = 0; |
unsigned long bg = 0; |
9896 |
|
int row_width; |
9897 |
|
|
9898 |
if (img->mask) |
if (img->mask) |
9899 |
{ |
{ |
9900 |
XFreePixmap (FRAME_X_DISPLAY (f), img->mask); |
DeleteObject (img->mask); |
9901 |
img->mask = None; |
img->mask = NULL; |
9902 |
img->background_transparent_valid = 0; |
img->background_transparent_valid = 0; |
9903 |
} |
} |
9904 |
|
|
9905 |
/* Create an image and pixmap serving as mask. */ |
/* Create the bit array serving as mask. */ |
9906 |
rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1, |
row_width = (img->width + 7) / 8; |
9907 |
&mask_img, &img->mask); |
mask_img = xmalloc (row_width * img->height); |
9908 |
if (!rc) |
bzero (mask_img, row_width * img->height); |
9909 |
return 0; |
|
9910 |
|
/* Create a memory device context for IMG->pixmap. */ |
9911 |
/* Get the X image of IMG->pixmap. */ |
frame_dc = get_frame_dc (f); |
9912 |
ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height, |
img_dc = CreateCompatibleDC (frame_dc); |
9913 |
~0, ZPixmap); |
release_frame_dc (f, frame_dc); |
9914 |
|
prev = SelectObject (img_dc, img->pixmap); |
9915 |
|
|
9916 |
/* Determine the background color of ximg. If HOW is `(R G B)' |
/* Determine the background color of img_dc. If HOW is `(R G B)' |
9917 |
take that as color. Otherwise, use the image's background color. */ |
take that as color. Otherwise, use the image's background color. */ |
9918 |
use_img_background = 1; |
use_img_background = 1; |
9919 |
|
|
9920 |
if (CONSP (how)) |
if (CONSP (how)) |
9921 |
{ |
{ |
9922 |
int rgb[3], i; |
int rgb[3], i; |
9931 |
{ |
{ |
9932 |
char color_name[30]; |
char color_name[30]; |
9933 |
sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); |
sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]); |
9934 |
bg = x_alloc_image_color (f, img, build_string (color_name), 0); |
bg = x_alloc_image_color (f, img, build_string (color_name), 0) |
9935 |
|
& 0x00ffffff; /* Filter out palette info. */ |
9936 |
use_img_background = 0; |
use_img_background = 0; |
9937 |
} |
} |
9938 |
} |
} |
9939 |
|
|
9940 |
if (use_img_background) |
if (use_img_background) |
9941 |
bg = four_corners_best (ximg, img->width, img->height); |
bg = four_corners_best (img_dc, img->width, img->height); |
9942 |
|
|
9943 |
/* Set all bits in mask_img to 1 whose color in ximg is different |
/* Set all bits in mask_img to 1 whose color in ximg is different |
9944 |
from the background color bg. */ |
from the background color bg. */ |
9945 |
for (y = 0; y < img->height; ++y) |
for (y = 0; y < img->height; ++y) |
9946 |
for (x = 0; x < img->width; ++x) |
for (x = 0; x < img->width; ++x) |
9947 |
XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg); |
{ |
9948 |
|
COLORREF p = GetPixel (img_dc, x, y); |
9949 |
|
if (p != bg) |
9950 |
|
mask_img[y * row_width + x / 8] |= 1 << (x % 8); |
9951 |
|
} |
9952 |
|
|
9953 |
|
/* Create the mask image. */ |
9954 |
|
img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height, |
9955 |
|
mask_img); |
9956 |
|
|
9957 |
/* Fill in the background_transparent field while we have the mask handy. */ |
/* Fill in the background_transparent field while we have the mask handy. */ |
9958 |
image_background_transparent (img, f, mask_img); |
SelectObject (img_dc, img->mask); |
9959 |
|
|
9960 |
|
image_background_transparent (img, f, img_dc); |
9961 |
|
|
9962 |
/* Put mask_img into img->mask. */ |
/* Put mask_img into img->mask. */ |
9963 |
x_put_x_image (f, mask_img, img->mask, img->width, img->height); |
x_destroy_x_image ((XImage *)mask_img); |
9964 |
x_destroy_x_image (mask_img); |
SelectObject (img_dc, prev); |
9965 |
XDestroyImage (ximg); |
DeleteDC (img_dc); |
9966 |
|
|
9967 |
return 1; |
return 1; |
|
#else |
|
|
return 0; |
|
|
#endif |
|
9968 |
} |
} |
9969 |
|
|
9970 |
|
|
10006 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
10007 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
10008 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
10009 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
10010 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
10011 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
10012 |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
10035 |
Lisp_Object object; |
Lisp_Object object; |
10036 |
{ |
{ |
10037 |
struct image_keyword fmt[PBM_LAST]; |
struct image_keyword fmt[PBM_LAST]; |
10038 |
|
|
10039 |
bcopy (pbm_format, fmt, sizeof fmt); |
bcopy (pbm_format, fmt, sizeof fmt); |
10040 |
|
|
10041 |
if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm) |
if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm)) |
|
|| (fmt[PBM_ASCENT].count |
|
|
&& XFASTINT (fmt[PBM_ASCENT].value) > 100)) |
|
10042 |
return 0; |
return 0; |
10043 |
|
|
10044 |
/* Must specify either :data or :file. */ |
/* Must specify either :data or :file. */ |
10086 |
|
|
10087 |
/* Read FILE into memory. Value is a pointer to a buffer allocated |
/* Read FILE into memory. Value is a pointer to a buffer allocated |
10088 |
with xmalloc holding FILE's contents. Value is null if an error |
with xmalloc holding FILE's contents. Value is null if an error |
10089 |
occured. *SIZE is set to the size of the file. */ |
occurred. *SIZE is set to the size of the file. */ |
10090 |
|
|
10091 |
static char * |
static char * |
10092 |
pbm_read_file (file, size) |
pbm_read_file (file, size) |
10097 |
char *buf = NULL; |
char *buf = NULL; |
10098 |
struct stat st; |
struct stat st; |
10099 |
|
|
10100 |
if (stat (XSTRING (file)->data, &st) == 0 |
if (stat (SDATA (file), &st) == 0 |
10101 |
&& (fp = fopen (XSTRING (file)->data, "r")) != NULL |
&& (fp = fopen (SDATA (file), "rb")) != NULL |
10102 |
&& (buf = (char *) xmalloc (st.st_size), |
&& (buf = (char *) xmalloc (st.st_size), |
10103 |
fread (buf, 1, st.st_size, fp) == st.st_size)) |
fread (buf, 1, st.st_size, fp) == st.st_size)) |
10104 |
{ |
{ |
10115 |
buf = NULL; |
buf = NULL; |
10116 |
} |
} |
10117 |
} |
} |
10118 |
|
|
10119 |
return buf; |
return buf; |
10120 |
} |
} |
10121 |
|
|
10122 |
|
|
10123 |
/* Load PBM image IMG for use on frame F. */ |
/* Load PBM image IMG for use on frame F. */ |
10124 |
|
|
10125 |
static int |
static int |
10126 |
pbm_load (f, img) |
pbm_load (f, img) |
10127 |
struct frame *f; |
struct frame *f; |
10128 |
struct image *img; |
struct image *img; |
10151 |
return 0; |
return 0; |
10152 |
} |
} |
10153 |
|
|
10154 |
contents = slurp_file (XSTRING (file)->data, &size); |
contents = slurp_file (SDATA (file), &size); |
10155 |
if (contents == NULL) |
if (contents == NULL) |
10156 |
{ |
{ |
10157 |
image_error ("Error reading `%s'", file, Qnil); |
image_error ("Error reading `%s'", file, Qnil); |
10166 |
{ |
{ |
10167 |
Lisp_Object data; |
Lisp_Object data; |
10168 |
data = image_spec_value (img->spec, QCdata, NULL); |
data = image_spec_value (img->spec, QCdata, NULL); |
10169 |
p = XSTRING (data)->data; |
p = SDATA (data); |
10170 |
end = p + STRING_BYTES (XSTRING (data)); |
end = p + SBYTES (data); |
10171 |
} |
} |
10172 |
|
|
10173 |
/* Check magic number. */ |
/* Check magic number. */ |
10185 |
case '1': |
case '1': |
10186 |
raw_p = 0, type = PBM_MONO; |
raw_p = 0, type = PBM_MONO; |
10187 |
break; |
break; |
10188 |
|
|
10189 |
case '2': |
case '2': |
10190 |
raw_p = 0, type = PBM_GRAY; |
raw_p = 0, type = PBM_GRAY; |
10191 |
break; |
break; |
10197 |
case '4': |
case '4': |
10198 |
raw_p = 1, type = PBM_MONO; |
raw_p = 1, type = PBM_MONO; |
10199 |
break; |
break; |
10200 |
|
|
10201 |
case '5': |
case '5': |
10202 |
raw_p = 1, type = PBM_GRAY; |
raw_p = 1, type = PBM_GRAY; |
10203 |
break; |
break; |
10204 |
|
|
10205 |
case '6': |
case '6': |
10206 |
raw_p = 1, type = PBM_COLOR; |
raw_p = 1, type = PBM_COLOR; |
10207 |
break; |
break; |
10222 |
if (raw_p && max_color_idx > 255) |
if (raw_p && max_color_idx > 255) |
10223 |
max_color_idx = 255; |
max_color_idx = 255; |
10224 |
} |
} |
10225 |
|
|
10226 |
if (width < 0 |
if (width < 0 |
10227 |
|| height < 0 |
|| height < 0 |
10228 |
|| (type != PBM_MONO && max_color_idx < 0)) |
|| (type != PBM_MONO && max_color_idx < 0)) |
10246 |
/* Parse the image specification. */ |
/* Parse the image specification. */ |
10247 |
bcopy (pbm_format, fmt, sizeof fmt); |
bcopy (pbm_format, fmt, sizeof fmt); |
10248 |
parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); |
parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm); |
10249 |
|
|
10250 |
/* Get foreground and background colors, maybe allocate colors. */ |
/* Get foreground and background colors, maybe allocate colors. */ |
10251 |
if (fmt[PBM_FOREGROUND].count |
if (fmt[PBM_FOREGROUND].count |
10252 |
&& STRINGP (fmt[PBM_FOREGROUND].value)) |
&& STRINGP (fmt[PBM_FOREGROUND].value)) |
10281 |
for (x = 0; x < width; ++x) |
for (x = 0; x < width; ++x) |
10282 |
{ |
{ |
10283 |
int r, g, b; |
int r, g, b; |
10284 |
|
|
10285 |
if (type == PBM_GRAY) |
if (type == PBM_GRAY) |
10286 |
r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end); |
r = g = b = raw_p ? *p++ : pbm_scan_number (&p, end); |
10287 |
else if (raw_p) |
else if (raw_p) |
10296 |
g = pbm_scan_number (&p, end); |
g = pbm_scan_number (&p, end); |
10297 |
b = pbm_scan_number (&p, end); |
b = pbm_scan_number (&p, end); |
10298 |
} |
} |
10299 |
|
|
10300 |
if (r < 0 || g < 0 || b < 0) |
if (r < 0 || g < 0 || b < 0) |
10301 |
{ |
{ |
10302 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
10304 |
img->spec, Qnil); |
img->spec, Qnil); |
10305 |
goto error; |
goto error; |
10306 |
} |
} |
10307 |
|
|
10308 |
/* RGB values are now in the range 0..max_color_idx. |
/* RGB values are now in the range 0..max_color_idx. |
10309 |
Scale this to the range 0..0xff supported by W32. */ |
Scale this to the range 0..0xff supported by W32. */ |
10310 |
r = (int) ((double) r * 255 / max_color_idx); |
r = (int) ((double) r * 255 / max_color_idx); |
10328 |
/* Maybe fill in the background field while we have ximg handy. */ |
/* Maybe fill in the background field while we have ximg handy. */ |
10329 |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
10330 |
IMAGE_BACKGROUND (img, f, ximg); |
IMAGE_BACKGROUND (img, f, ximg); |
10331 |
|
|
10332 |
/* Put the image into a pixmap. */ |
/* Put the image into a pixmap. */ |
10333 |
x_put_x_image (f, ximg, img->pixmap, width, height); |
x_put_x_image (f, ximg, img->pixmap, width, height); |
10334 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
10335 |
|
|
10336 |
img->width = width; |
img->width = width; |
10337 |
img->height = height; |
img->height = height; |
10338 |
|
|
10384 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
10385 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
10386 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
10387 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
10388 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
10389 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
10390 |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
10404 |
NULL |
NULL |
10405 |
}; |
}; |
10406 |
|
|
10407 |
|
/* PNG library details. */ |
10408 |
|
|
10409 |
|
DEF_IMGLIB_FN (png_get_io_ptr); |
10410 |
|
DEF_IMGLIB_FN (png_check_sig); |
10411 |
|
DEF_IMGLIB_FN (png_create_read_struct); |
10412 |
|
DEF_IMGLIB_FN (png_create_info_struct); |
10413 |
|
DEF_IMGLIB_FN (png_destroy_read_struct); |
10414 |
|
DEF_IMGLIB_FN (png_set_read_fn); |
10415 |
|
DEF_IMGLIB_FN (png_init_io); |
10416 |
|
DEF_IMGLIB_FN (png_set_sig_bytes); |
10417 |
|
DEF_IMGLIB_FN (png_read_info); |
10418 |
|
DEF_IMGLIB_FN (png_get_IHDR); |
10419 |
|
DEF_IMGLIB_FN (png_get_valid); |
10420 |
|
DEF_IMGLIB_FN (png_set_strip_16); |
10421 |
|
DEF_IMGLIB_FN (png_set_expand); |
10422 |
|
DEF_IMGLIB_FN (png_set_gray_to_rgb); |
10423 |
|
DEF_IMGLIB_FN (png_set_background); |
10424 |
|
DEF_IMGLIB_FN (png_get_bKGD); |
10425 |
|
DEF_IMGLIB_FN (png_read_update_info); |
10426 |
|
DEF_IMGLIB_FN (png_get_channels); |
10427 |
|
DEF_IMGLIB_FN (png_get_rowbytes); |
10428 |
|
DEF_IMGLIB_FN (png_read_image); |
10429 |
|
DEF_IMGLIB_FN (png_read_end); |
10430 |
|
DEF_IMGLIB_FN (png_error); |
10431 |
|
|
10432 |
|
static int |
10433 |
|
init_png_functions (library) |
10434 |
|
HMODULE library; |
10435 |
|
{ |
10436 |
|
LOAD_IMGLIB_FN (library, png_get_io_ptr); |
10437 |
|
LOAD_IMGLIB_FN (library, png_check_sig); |
10438 |
|
LOAD_IMGLIB_FN (library, png_create_read_struct); |
10439 |
|
LOAD_IMGLIB_FN (library, png_create_info_struct); |
10440 |
|
LOAD_IMGLIB_FN (library, png_destroy_read_struct); |
10441 |
|
LOAD_IMGLIB_FN (library, png_set_read_fn); |
10442 |
|
LOAD_IMGLIB_FN (library, png_init_io); |
10443 |
|
LOAD_IMGLIB_FN (library, png_set_sig_bytes); |
10444 |
|
LOAD_IMGLIB_FN (library, png_read_info); |
10445 |
|
LOAD_IMGLIB_FN (library, png_get_IHDR); |
10446 |
|
LOAD_IMGLIB_FN (library, png_get_valid); |
10447 |
|
LOAD_IMGLIB_FN (library, png_set_strip_16); |
10448 |
|
LOAD_IMGLIB_FN (library, png_set_expand); |
10449 |
|
LOAD_IMGLIB_FN (library, png_set_gray_to_rgb); |
10450 |
|
LOAD_IMGLIB_FN (library, png_set_background); |
10451 |
|
LOAD_IMGLIB_FN (library, png_get_bKGD); |
10452 |
|
LOAD_IMGLIB_FN (library, png_read_update_info); |
10453 |
|
LOAD_IMGLIB_FN (library, png_get_channels); |
10454 |
|
LOAD_IMGLIB_FN (library, png_get_rowbytes); |
10455 |
|
LOAD_IMGLIB_FN (library, png_read_image); |
10456 |
|
LOAD_IMGLIB_FN (library, png_read_end); |
10457 |
|
LOAD_IMGLIB_FN (library, png_error); |
10458 |
|
return 1; |
10459 |
|
} |
10460 |
|
|
10461 |
/* Return non-zero if OBJECT is a valid PNG image specification. */ |
/* Return non-zero if OBJECT is a valid PNG image specification. */ |
10462 |
|
|
10466 |
{ |
{ |
10467 |
struct image_keyword fmt[PNG_LAST]; |
struct image_keyword fmt[PNG_LAST]; |
10468 |
bcopy (png_format, fmt, sizeof fmt); |
bcopy (png_format, fmt, sizeof fmt); |
10469 |
|
|
10470 |
if (!parse_image_spec (object, fmt, PNG_LAST, Qpng) |
if (!parse_image_spec (object, fmt, PNG_LAST, Qpng)) |
|
|| (fmt[PNG_ASCENT].count |
|
|
&& XFASTINT (fmt[PNG_ASCENT].value) > 100)) |
|
10471 |
return 0; |
return 0; |
10472 |
|
|
10473 |
/* Must specify either the :data or :file keyword. */ |
/* Must specify either the :data or :file keyword. */ |
10519 |
png_size_t length; |
png_size_t length; |
10520 |
{ |
{ |
10521 |
struct png_memory_storage *tbr |
struct png_memory_storage *tbr |
10522 |
= (struct png_memory_storage *) png_get_io_ptr (png_ptr); |
= (struct png_memory_storage *) fn_png_get_io_ptr (png_ptr); |
10523 |
|
|
10524 |
if (length > tbr->len - tbr->index) |
if (length > tbr->len - tbr->index) |
10525 |
png_error (png_ptr, "Read error"); |
fn_png_error (png_ptr, "Read error"); |
10526 |
|
|
10527 |
bcopy (tbr->bytes + tbr->index, data, length); |
bcopy (tbr->bytes + tbr->index, data, length); |
10528 |
tbr->index = tbr->index + length; |
tbr->index = tbr->index + length; |
10529 |
} |
} |
10545 |
png_info *info_ptr = NULL, *end_info = NULL; |
png_info *info_ptr = NULL, *end_info = NULL; |
10546 |
FILE *volatile fp = NULL; |
FILE *volatile fp = NULL; |
10547 |
png_byte sig[8]; |
png_byte sig[8]; |
10548 |
png_byte *volatile pixels = NULL; |
png_byte * volatile pixels = NULL; |
10549 |
png_byte **volatile rows = NULL; |
png_byte ** volatile rows = NULL; |
10550 |
png_uint_32 width, height; |
png_uint_32 width, height; |
10551 |
int bit_depth, color_type, interlace_type; |
int bit_depth, color_type, interlace_type; |
10552 |
png_byte channels; |
png_byte channels; |
10553 |
png_uint_32 row_bytes; |
png_uint_32 row_bytes; |
10554 |
int transparent_p; |
int transparent_p; |
|
char *gamma_str; |
|
10555 |
double screen_gamma, image_gamma; |
double screen_gamma, image_gamma; |
10556 |
int intent; |
int intent; |
10557 |
struct png_memory_storage tbr; /* Data to be read */ |
struct png_memory_storage tbr; /* Data to be read */ |
10566 |
{ |
{ |
10567 |
file = x_find_image_file (specified_file); |
file = x_find_image_file (specified_file); |
10568 |
if (!STRINGP (file)) |
if (!STRINGP (file)) |
10569 |
{ |
{ |
10570 |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
10571 |
UNGCPRO; |
UNGCPRO; |
10572 |
return 0; |
return 0; |
10573 |
} |
} |
10574 |
|
|
10575 |
/* Open the image file. */ |
/* Open the image file. */ |
10576 |
fp = fopen (XSTRING (file)->data, "rb"); |
fp = fopen (SDATA (file), "rb"); |
10577 |
if (!fp) |
if (!fp) |
10578 |
{ |
{ |
10579 |
image_error ("Cannot open image file `%s'", file, Qnil); |
image_error ("Cannot open image file `%s'", file, Qnil); |
10580 |
UNGCPRO; |
UNGCPRO; |
10581 |
fclose (fp); |
fclose (fp); |
10582 |
return 0; |
return 0; |
10583 |
} |
} |
10584 |
|
|
10585 |
/* Check PNG signature. */ |
/* Check PNG signature. */ |
10586 |
if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
10587 |
|| !png_check_sig (sig, sizeof sig)) |
|| !fn_png_check_sig (sig, sizeof sig)) |
10588 |
{ |
{ |
10589 |
image_error ("Not a PNG file:` %s'", file, Qnil); |
image_error ("Not a PNG file: `%s'", file, Qnil); |
10590 |
UNGCPRO; |
UNGCPRO; |
10591 |
fclose (fp); |
fclose (fp); |
10592 |
return 0; |
return 0; |
10593 |
} |
} |
10594 |
} |
} |
10595 |
else |
else |
10596 |
{ |
{ |
10597 |
/* Read from memory. */ |
/* Read from memory. */ |
10598 |
tbr.bytes = XSTRING (specified_data)->data; |
tbr.bytes = SDATA (specified_data); |
10599 |
tbr.len = STRING_BYTES (XSTRING (specified_data)); |
tbr.len = SBYTES (specified_data); |
10600 |
tbr.index = 0; |
tbr.index = 0; |
10601 |
|
|
10602 |
/* Check PNG signature. */ |
/* Check PNG signature. */ |
10603 |
if (tbr.len < sizeof sig |
if (tbr.len < sizeof sig |
10604 |
|| !png_check_sig (tbr.bytes, sizeof sig)) |
|| !fn_png_check_sig (tbr.bytes, sizeof sig)) |
10605 |
{ |
{ |
10606 |
image_error ("Not a PNG image: `%s'", img->spec, Qnil); |
image_error ("Not a PNG image: `%s'", img->spec, Qnil); |
10607 |
UNGCPRO; |
UNGCPRO; |
10613 |
} |
} |
10614 |
|
|
10615 |
/* Initialize read and info structs for PNG lib. */ |
/* Initialize read and info structs for PNG lib. */ |
10616 |
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, |
png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, |
10617 |
my_png_error, my_png_warning); |
my_png_error, my_png_warning); |
10618 |
if (!png_ptr) |
if (!png_ptr) |
10619 |
{ |
{ |
10620 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
10622 |
return 0; |
return 0; |
10623 |
} |
} |
10624 |
|
|
10625 |
info_ptr = png_create_info_struct (png_ptr); |
info_ptr = fn_png_create_info_struct (png_ptr); |
10626 |
if (!info_ptr) |
if (!info_ptr) |
10627 |
{ |
{ |
10628 |
png_destroy_read_struct (&png_ptr, NULL, NULL); |
fn_png_destroy_read_struct (&png_ptr, NULL, NULL); |
10629 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
10630 |
UNGCPRO; |
UNGCPRO; |
10631 |
return 0; |
return 0; |
10632 |
} |
} |
10633 |
|
|
10634 |
end_info = png_create_info_struct (png_ptr); |
end_info = fn_png_create_info_struct (png_ptr); |
10635 |
if (!end_info) |
if (!end_info) |
10636 |
{ |
{ |
10637 |
png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); |
10638 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
10639 |
UNGCPRO; |
UNGCPRO; |
10640 |
return 0; |
return 0; |
10646 |
{ |
{ |
10647 |
error: |
error: |
10648 |
if (png_ptr) |
if (png_ptr) |
10649 |
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
10650 |
xfree (pixels); |
xfree (pixels); |
10651 |
xfree (rows); |
xfree (rows); |
10652 |
if (fp) fclose (fp); |
if (fp) fclose (fp); |
10656 |
|
|
10657 |
/* Read image info. */ |
/* Read image info. */ |
10658 |
if (!NILP (specified_data)) |
if (!NILP (specified_data)) |
10659 |
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); |
10660 |
else |
else |
10661 |
png_init_io (png_ptr, fp); |
fn_png_init_io (png_ptr, fp); |
10662 |
|
|
10663 |
png_set_sig_bytes (png_ptr, sizeof sig); |
fn_png_set_sig_bytes (png_ptr, sizeof sig); |
10664 |
png_read_info (png_ptr, info_ptr); |
fn_png_read_info (png_ptr, info_ptr); |
10665 |
png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, |
fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, |
10666 |
&interlace_type, NULL, NULL); |
&interlace_type, NULL, NULL); |
10667 |
|
|
10668 |
/* If image contains simply transparency data, we prefer to |
/* If image contains simply transparency data, we prefer to |
10669 |
construct a clipping mask. */ |
construct a clipping mask. */ |
10670 |
if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) |
if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) |
10671 |
transparent_p = 1; |
transparent_p = 1; |
10672 |
else |
else |
10673 |
transparent_p = 0; |
transparent_p = 0; |
10674 |
|
|
10675 |
/* This function is easier to write if we only have to handle |
/* This function is easier to write if we only have to handle |
10676 |
one data format: RGB or RGBA with 8 bits per channel. Let's |
one data format: RGB or RGBA with 8 bits per channel. Let's |
10677 |
transform other formats into that format. */ |
transform other formats into that format. */ |
10678 |
|
|
10679 |
/* Strip more than 8 bits per channel. */ |
/* Strip more than 8 bits per channel. */ |
10680 |
if (bit_depth == 16) |
if (bit_depth == 16) |
10681 |
png_set_strip_16 (png_ptr); |
fn_png_set_strip_16 (png_ptr); |
10682 |
|
|
10683 |
/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel |
/* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel |
10684 |
if available. */ |
if available. */ |
10685 |
png_set_expand (png_ptr); |
fn_png_set_expand (png_ptr); |
10686 |
|
|
10687 |
/* Convert grayscale images to RGB. */ |
/* Convert grayscale images to RGB. */ |
10688 |
if (color_type == PNG_COLOR_TYPE_GRAY |
if (color_type == PNG_COLOR_TYPE_GRAY |
10689 |
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
|| color_type == PNG_COLOR_TYPE_GRAY_ALPHA) |
10690 |
png_set_gray_to_rgb (png_ptr); |
fn_png_set_gray_to_rgb (png_ptr); |
10691 |
|
|
10692 |
/* The value 2.2 is a guess for PC monitors from PNG example.c. */ |
screen_gamma = (f->gamma ? 1 / f->gamma / 0.45455 : 2.2); |
|
gamma_str = getenv ("SCREEN_GAMMA"); |
|
|
screen_gamma = gamma_str ? atof (gamma_str) : 2.2; |
|
10693 |
|
|
10694 |
|
#if 0 /* Avoid double gamma correction for PNG images. */ |
10695 |
/* Tell the PNG lib to handle gamma correction for us. */ |
/* Tell the PNG lib to handle gamma correction for us. */ |
|
|
|
10696 |
#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) |
#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) |
10697 |
if (png_get_sRGB (png_ptr, info_ptr, &intent)) |
if (png_get_sRGB (png_ptr, info_ptr, &intent)) |
10698 |
/* There is a special chunk in the image specifying the gamma. */ |
/* The libpng documentation says this is right in this case. */ |
10699 |
png_set_sRGB (png_ptr, info_ptr, intent); |
png_set_gamma (png_ptr, screen_gamma, 0.45455); |
10700 |
else |
else |
10701 |
#endif |
#endif |
10702 |
if (png_get_gAMA (png_ptr, info_ptr, &image_gamma)) |
if (png_get_gAMA (png_ptr, info_ptr, &image_gamma)) |
10703 |
/* Image contains gamma information. */ |
/* Image contains gamma information. */ |
10704 |
png_set_gamma (png_ptr, screen_gamma, image_gamma); |
png_set_gamma (png_ptr, screen_gamma, image_gamma); |
10705 |
else |
else |
10706 |
/* Use a default of 0.5 for the image gamma. */ |
/* Use the standard default for the image gamma. */ |
10707 |
png_set_gamma (png_ptr, screen_gamma, 0.5); |
png_set_gamma (png_ptr, screen_gamma, 0.45455); |
10708 |
|
#endif /* if 0 */ |
10709 |
|
|
10710 |
/* Handle alpha channel by combining the image with a background |
/* Handle alpha channel by combining the image with a background |
10711 |
color. Do this only if a real alpha channel is supplied. For |
color. Do this only if a real alpha channel is supplied. For |
10712 |
simple transparency, we prefer a clipping mask. */ |
simple transparency, we prefer a clipping mask. */ |
10713 |
if (!transparent_p) |
if (!transparent_p) |
10714 |
{ |
{ |
10715 |
png_color_16 *image_background; |
png_color_16 *image_bg; |
10716 |
Lisp_Object specified_bg |
Lisp_Object specified_bg |
10717 |
= image_spec_value (img->spec, QCbackground, NULL); |
= image_spec_value (img->spec, QCbackground, NULL); |
10718 |
|
|
|
|
|
10719 |
if (STRINGP (specified_bg)) |
if (STRINGP (specified_bg)) |
10720 |
/* The user specified `:background', use that. */ |
/* The user specified `:background', use that. */ |
10721 |
{ |
{ |
10722 |
COLORREF color; |
COLORREF color; |
10723 |
if (w32_defined_color (f, XSTRING (specified_bg)->data, &color, 0)) |
if (w32_defined_color (f, SDATA (specified_bg), &color, 0)) |
10724 |
{ |
{ |
10725 |
png_color_16 user_bg; |
png_color_16 user_bg; |
10726 |
|
|
10727 |
bzero (&user_bg, sizeof user_bg); |
bzero (&user_bg, sizeof user_bg); |
10728 |
user_bg.red = color.red; |
user_bg.red = 256 * GetRValue (color); |
10729 |
user_bg.green = color.green; |
user_bg.green = 256 * GetGValue (color); |
10730 |
user_bg.blue = color.blue; |
user_bg.blue = 256 * GetBValue (color); |
10731 |
|
|
10732 |
png_set_background (png_ptr, &user_bg, |
fn_png_set_background (png_ptr, &user_bg, |
10733 |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
10734 |
} |
} |
10735 |
} |
} |
10736 |
else if (png_get_bKGD (png_ptr, info_ptr, &image_background)) |
else if (fn_png_get_bKGD (png_ptr, info_ptr, &image_bg)) |
10737 |
/* Image contains a background color with which to |
/* Image contains a background color with which to |
10738 |
combine the image. */ |
combine the image. */ |
10739 |
png_set_background (png_ptr, image_background, |
fn_png_set_background (png_ptr, image_bg, |
10740 |
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); |
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); |
10741 |
else |
else |
10742 |
{ |
{ |
10743 |
/* Image does not contain a background color with which |
/* Image does not contain a background color with which |
10744 |
to combine the image data via an alpha channel. Use |
to combine the image data via an alpha channel. Use |
10745 |
the frame's background instead. */ |
the frame's background instead. */ |
10746 |
XColor color; |
COLORREF color; |
|
Colormap cmap; |
|
10747 |
png_color_16 frame_background; |
png_color_16 frame_background; |
10748 |
|
color = FRAME_BACKGROUND_PIXEL (f); |
10749 |
|
#if 0 /* TODO : Colormap support. */ |
10750 |
|
Colormap cmap; |
10751 |
|
|
10752 |
cmap = FRAME_X_COLORMAP (f); |
cmap = FRAME_X_COLORMAP (f); |
|
color.pixel = FRAME_BACKGROUND_PIXEL (f); |
|
10753 |
x_query_color (f, &color); |
x_query_color (f, &color); |
10754 |
|
#endif |
10755 |
|
|
10756 |
bzero (&frame_background, sizeof frame_background); |
bzero (&frame_background, sizeof frame_background); |
10757 |
frame_background.red = color.red; |
frame_background.red = 256 * GetRValue (color); |
10758 |
frame_background.green = color.green; |
frame_background.green = 256 * GetGValue (color); |
10759 |
frame_background.blue = color.blue; |
frame_background.blue = 256 * GetBValue (color); |
10760 |
|
|
10761 |
png_set_background (png_ptr, &frame_background, |
fn_png_set_background (png_ptr, &frame_background, |
10762 |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); |
10763 |
} |
} |
10764 |
} |
} |
10765 |
|
|
10766 |
/* Update info structure. */ |
/* Update info structure. */ |
10767 |
png_read_update_info (png_ptr, info_ptr); |
fn_png_read_update_info (png_ptr, info_ptr); |
10768 |
|
|
10769 |
/* Get number of channels. Valid values are 1 for grayscale images |
/* Get number of channels. Valid values are 1 for grayscale images |
10770 |
and images with a palette, 2 for grayscale images with transparency |
and images with a palette, 2 for grayscale images with transparency |
10771 |
information (alpha channel), 3 for RGB images, and 4 for RGB |
information (alpha channel), 3 for RGB images, and 4 for RGB |
10772 |
images with alpha channel, i.e. RGBA. If conversions above were |
images with alpha channel, i.e. RGBA. If conversions above were |
10773 |
sufficient we should only have 3 or 4 channels here. */ |
sufficient we should only have 3 or 4 channels here. */ |
10774 |
channels = png_get_channels (png_ptr, info_ptr); |
channels = fn_png_get_channels (png_ptr, info_ptr); |
10775 |
xassert (channels == 3 || channels == 4); |
xassert (channels == 3 || channels == 4); |
10776 |
|
|
10777 |
/* Number of bytes needed for one row of the image. */ |
/* Number of bytes needed for one row of the image. */ |
10778 |
row_bytes = png_get_rowbytes (png_ptr, info_ptr); |
row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr); |
10779 |
|
|
10780 |
/* Allocate memory for the image. */ |
/* Allocate memory for the image. */ |
10781 |
pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); |
pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); |
10784 |
rows[i] = pixels + i * row_bytes; |
rows[i] = pixels + i * row_bytes; |
10785 |
|
|
10786 |
/* Read the entire image. */ |
/* Read the entire image. */ |
10787 |
png_read_image (png_ptr, rows); |
fn_png_read_image (png_ptr, rows); |
10788 |
png_read_end (png_ptr, info_ptr); |
fn_png_read_end (png_ptr, info_ptr); |
10789 |
if (fp) |
if (fp) |
10790 |
{ |
{ |
10791 |
fclose (fp); |
fclose (fp); |
10796 |
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, |
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, |
10797 |
&img->pixmap)) |
&img->pixmap)) |
10798 |
goto error; |
goto error; |
10799 |
|
|
10800 |
/* Create an image and pixmap serving as mask if the PNG image |
/* Create an image and pixmap serving as mask if the PNG image |
10801 |
contains an alpha channel. */ |
contains an alpha channel. */ |
10802 |
if (channels == 4 |
if (channels == 4 |
10805 |
&mask_img, &img->mask)) |
&mask_img, &img->mask)) |
10806 |
{ |
{ |
10807 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
10808 |
XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap); |
DeleteObject (img->pixmap); |
10809 |
img->pixmap = 0; |
img->pixmap = 0; |
10810 |
goto error; |
goto error; |
10811 |
} |
} |
|
|
|
10812 |
/* Fill the X image and mask from PNG data. */ |
/* Fill the X image and mask from PNG data. */ |
10813 |
|
#if 0 /* TODO: Color tables. */ |
10814 |
init_color_table (); |
init_color_table (); |
10815 |
|
#endif |
10816 |
|
|
10817 |
for (y = 0; y < height; ++y) |
for (y = 0; y < height; ++y) |
10818 |
{ |
{ |
10822 |
{ |
{ |
10823 |
unsigned r, g, b; |
unsigned r, g, b; |
10824 |
|
|
10825 |
r = *p++ << 8; |
r = *p++; |
10826 |
g = *p++ << 8; |
g = *p++; |
10827 |
b = *p++ << 8; |
b = *p++; |
10828 |
|
#if 0 /* TODO: Color tables. */ |
10829 |
XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); |
XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b)); |
10830 |
|
#else |
10831 |
|
XPutPixel (ximg, x, y, PALETTERGB (r, g, b)); |
10832 |
|
#endif |
10833 |
/* An alpha channel, aka mask channel, associates variable |
/* An alpha channel, aka mask channel, associates variable |
10834 |
transparency with an image. Where other image formats |
transparency with an image. Where other image formats |
10835 |
support binary transparency---fully transparent or fully |
support binary transparency---fully transparent or fully |
10836 |
opaque---PNG allows up to 254 levels of partial transparency. |
opaque---PNG allows up to 254 levels of partial transparency. |
10837 |
The PNG library implements partial transparency by combining |
The PNG library implements partial transparency by combining |
10838 |
the image with a specified background color. |
the image with a specified background color. |
10839 |
|
|
10840 |
I'm not sure how to handle this here nicely: because the |
I'm not sure how to handle this here nicely: because the |
10841 |
background on which the image is displayed may change, for |
background on which the image is displayed may change, for |
10842 |
real alpha channel support, it would be necessary to create |
real alpha channel support, it would be necessary to create |
10843 |
a new image for each possible background. |
a new image for each possible background. |
10844 |
|
|
10845 |
What I'm doing now is that a mask is created if we have |
What I'm doing now is that a mask is created if we have |
10846 |
boolean transparency information. Otherwise I'm using |
boolean transparency information. Otherwise I'm using |
10860 |
overrode it. */ |
overrode it. */ |
10861 |
{ |
{ |
10862 |
png_color_16 *bg; |
png_color_16 *bg; |
10863 |
if (png_get_bKGD (png_ptr, info_ptr, &bg)) |
if (fn_png_get_bKGD (png_ptr, info_ptr, &bg)) |
10864 |
{ |
{ |
10865 |
|
#if 0 /* TODO: Color tables. */ |
10866 |
img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); |
img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue); |
10867 |
|
#else |
10868 |
|
img->background = PALETTERGB (bg->red / 256, bg->green / 256, |
10869 |
|
bg->blue / 256); |
10870 |
|
#endif |
10871 |
img->background_valid = 1; |
img->background_valid = 1; |
10872 |
} |
} |
10873 |
} |
} |
10874 |
|
|
10875 |
|
#if 0 /* TODO: Color tables. */ |
10876 |
/* Remember colors allocated for this image. */ |
/* Remember colors allocated for this image. */ |
10877 |
img->colors = colors_in_color_table (&img->ncolors); |
img->colors = colors_in_color_table (&img->ncolors); |
10878 |
free_color_table (); |
free_color_table (); |
10879 |
|
#endif |
10880 |
|
|
10881 |
/* Clean up. */ |
/* Clean up. */ |
10882 |
png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); |
10883 |
xfree (rows); |
xfree (rows); |
10884 |
xfree (pixels); |
xfree (pixels); |
10885 |
|
|
10965 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
10966 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
10967 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
10968 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
10969 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
10970 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
10971 |
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
10986 |
}; |
}; |
10987 |
|
|
10988 |
|
|
10989 |
|
/* JPEG library details. */ |
10990 |
|
DEF_IMGLIB_FN (jpeg_CreateDecompress); |
10991 |
|
DEF_IMGLIB_FN (jpeg_start_decompress); |
10992 |
|
DEF_IMGLIB_FN (jpeg_finish_decompress); |
10993 |
|
DEF_IMGLIB_FN (jpeg_destroy_decompress); |
10994 |
|
DEF_IMGLIB_FN (jpeg_read_header); |
10995 |
|
DEF_IMGLIB_FN (jpeg_read_scanlines); |
10996 |
|
DEF_IMGLIB_FN (jpeg_stdio_src); |
10997 |
|
DEF_IMGLIB_FN (jpeg_std_error); |
10998 |
|
DEF_IMGLIB_FN (jpeg_resync_to_restart); |
10999 |
|
|
11000 |
|
static int |
11001 |
|
init_jpeg_functions (library) |
11002 |
|
HMODULE library; |
11003 |
|
{ |
11004 |
|
LOAD_IMGLIB_FN (library, jpeg_finish_decompress); |
11005 |
|
LOAD_IMGLIB_FN (library, jpeg_read_scanlines); |
11006 |
|
LOAD_IMGLIB_FN (library, jpeg_start_decompress); |
11007 |
|
LOAD_IMGLIB_FN (library, jpeg_read_header); |
11008 |
|
LOAD_IMGLIB_FN (library, jpeg_stdio_src); |
11009 |
|
LOAD_IMGLIB_FN (library, jpeg_CreateDecompress); |
11010 |
|
LOAD_IMGLIB_FN (library, jpeg_destroy_decompress); |
11011 |
|
LOAD_IMGLIB_FN (library, jpeg_std_error); |
11012 |
|
LOAD_IMGLIB_FN (library, jpeg_resync_to_restart); |
11013 |
|
return 1; |
11014 |
|
} |
11015 |
|
|
11016 |
|
/* Wrapper since we can't directly assign the function pointer |
11017 |
|
to another function pointer that was declared more completely easily. */ |
11018 |
|
static boolean |
11019 |
|
jpeg_resync_to_restart_wrapper(cinfo, desired) |
11020 |
|
j_decompress_ptr cinfo; |
11021 |
|
int desired; |
11022 |
|
{ |
11023 |
|
return fn_jpeg_resync_to_restart (cinfo, desired); |
11024 |
|
} |
11025 |
|
|
11026 |
|
|
11027 |
/* Return non-zero if OBJECT is a valid JPEG image specification. */ |
/* Return non-zero if OBJECT is a valid JPEG image specification. */ |
11028 |
|
|
11029 |
static int |
static int |
11031 |
Lisp_Object object; |
Lisp_Object object; |
11032 |
{ |
{ |
11033 |
struct image_keyword fmt[JPEG_LAST]; |
struct image_keyword fmt[JPEG_LAST]; |
11034 |
|
|
11035 |
bcopy (jpeg_format, fmt, sizeof fmt); |
bcopy (jpeg_format, fmt, sizeof fmt); |
11036 |
|
|
11037 |
if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) |
if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg)) |
|
|| (fmt[JPEG_ASCENT].count |
|
|
&& XFASTINT (fmt[JPEG_ASCENT].value) > 100)) |
|
11038 |
return 0; |
return 0; |
11039 |
|
|
11040 |
/* Must specify either the :data or :file keyword. */ |
/* Must specify either the :data or :file keyword. */ |
11048 |
jmp_buf setjmp_buffer; |
jmp_buf setjmp_buffer; |
11049 |
}; |
}; |
11050 |
|
|
11051 |
|
|
11052 |
static void |
static void |
11053 |
my_error_exit (cinfo) |
my_error_exit (cinfo) |
11054 |
j_common_ptr cinfo; |
j_common_ptr cinfo; |
11057 |
longjmp (mgr->setjmp_buffer, 1); |
longjmp (mgr->setjmp_buffer, 1); |
11058 |
} |
} |
11059 |
|
|
11060 |
|
|
11061 |
/* Init source method for JPEG data source manager. Called by |
/* Init source method for JPEG data source manager. Called by |
11062 |
jpeg_read_header() before any data is actually read. See |
jpeg_read_header() before any data is actually read. See |
11063 |
libjpeg.doc from the JPEG lib distribution. */ |
libjpeg.doc from the JPEG lib distribution. */ |
11104 |
{ |
{ |
11105 |
if (num_bytes > src->bytes_in_buffer) |
if (num_bytes > src->bytes_in_buffer) |
11106 |
ERREXIT (cinfo, JERR_INPUT_EOF); |
ERREXIT (cinfo, JERR_INPUT_EOF); |
11107 |
|
|
11108 |
src->bytes_in_buffer -= num_bytes; |
src->bytes_in_buffer -= num_bytes; |
11109 |
src->next_input_byte += num_bytes; |
src->next_input_byte += num_bytes; |
11110 |
} |
} |
11142 |
src = (struct jpeg_source_mgr *) cinfo->src; |
src = (struct jpeg_source_mgr *) cinfo->src; |
11143 |
src->next_input_byte = data; |
src->next_input_byte = data; |
11144 |
} |
} |
11145 |
|
|
11146 |
src = (struct jpeg_source_mgr *) cinfo->src; |
src = (struct jpeg_source_mgr *) cinfo->src; |
11147 |
src->init_source = our_init_source; |
src->init_source = our_init_source; |
11148 |
src->fill_input_buffer = our_fill_input_buffer; |
src->fill_input_buffer = our_fill_input_buffer; |
11149 |
src->skip_input_data = our_skip_input_data; |
src->skip_input_data = our_skip_input_data; |
11150 |
src->resync_to_restart = jpeg_resync_to_restart; /* Use default method. */ |
src->resync_to_restart = jpeg_resync_to_restart_wrapper; /* Use default method. */ |
11151 |
src->term_source = our_term_source; |
src->term_source = our_term_source; |
11152 |
src->bytes_in_buffer = len; |
src->bytes_in_buffer = len; |
11153 |
src->next_input_byte = data; |
src->next_input_byte = data; |
11157 |
/* Load image IMG for use on frame F. Patterned after example.c |
/* Load image IMG for use on frame F. Patterned after example.c |
11158 |
from the JPEG lib. */ |
from the JPEG lib. */ |
11159 |
|
|
11160 |
static int |
static int |
11161 |
jpeg_load (f, img) |
jpeg_load (f, img) |
11162 |
struct frame *f; |
struct frame *f; |
11163 |
struct image *img; |
struct image *img; |
11185 |
{ |
{ |
11186 |
file = x_find_image_file (specified_file); |
file = x_find_image_file (specified_file); |
11187 |
if (!STRINGP (file)) |
if (!STRINGP (file)) |
11188 |
{ |
{ |
11189 |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
image_error ("Cannot find image file `%s'", specified_file, Qnil); |
11190 |
UNGCPRO; |
UNGCPRO; |
11191 |
return 0; |
return 0; |
11192 |
} |
} |
11193 |
|
|
11194 |
fp = fopen (XSTRING (file)->data, "r"); |
fp = fopen (SDATA (file), "rb"); |
11195 |
if (fp == NULL) |
if (fp == NULL) |
11196 |
{ |
{ |
11197 |
image_error ("Cannot open `%s'", file, Qnil); |
image_error ("Cannot open `%s'", file, Qnil); |
11198 |
UNGCPRO; |
UNGCPRO; |
11199 |
return 0; |
return 0; |
11200 |
} |
} |
11201 |
} |
} |
11202 |
|
|
11203 |
/* Customize libjpeg's error handling to call my_error_exit when an |
/* Customize libjpeg's error handling to call my_error_exit when an |
11204 |
error is detected. This function will perform a longjmp. */ |
error is detected. This function will perform a longjmp. */ |
11205 |
cinfo.err = jpeg_std_error (&mgr.pub); |
cinfo.err = fn_jpeg_std_error (&mgr.pub); |
11206 |
mgr.pub.error_exit = my_error_exit; |
mgr.pub.error_exit = my_error_exit; |
11207 |
|
|
11208 |
if ((rc = setjmp (mgr.setjmp_buffer)) != 0) |
if ((rc = setjmp (mgr.setjmp_buffer)) != 0) |
11209 |
{ |
{ |
11210 |
if (rc == 1) |
if (rc == 1) |
11215 |
image_error ("Error reading JPEG image `%s': %s", img->spec, |
image_error ("Error reading JPEG image `%s': %s", img->spec, |
11216 |
build_string (buffer)); |
build_string (buffer)); |
11217 |
} |
} |
11218 |
|
|
11219 |
/* Close the input file and destroy the JPEG object. */ |
/* Close the input file and destroy the JPEG object. */ |
11220 |
if (fp) |
if (fp) |
11221 |
fclose (fp); |
fclose ((FILE *) fp); |
11222 |
jpeg_destroy_decompress (&cinfo); |
fn_jpeg_destroy_decompress (&cinfo); |
11223 |
|
|
11224 |
/* If we already have an XImage, free that. */ |
/* If we already have an XImage, free that. */ |
11225 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
11226 |
|
|
11227 |
/* Free pixmap and colors. */ |
/* Free pixmap and colors. */ |
11228 |
x_clear_image (f, img); |
x_clear_image (f, img); |
11229 |
|
|
11230 |
UNGCPRO; |
UNGCPRO; |
11231 |
return 0; |
return 0; |
11232 |
} |
} |
11233 |
|
|
11234 |
/* Create the JPEG decompression object. Let it read from fp. |
/* Create the JPEG decompression object. Let it read from fp. |
11235 |
Read the JPEG image header. */ |
Read the JPEG image header. */ |
11236 |
jpeg_create_decompress (&cinfo); |
fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo)); |
11237 |
|
|
11238 |
if (NILP (specified_data)) |
if (NILP (specified_data)) |
11239 |
jpeg_stdio_src (&cinfo, fp); |
fn_jpeg_stdio_src (&cinfo, (FILE *) fp); |
11240 |
else |
else |
11241 |
jpeg_memory_src (&cinfo, XSTRING (specified_data)->data, |
jpeg_memory_src (&cinfo, SDATA (specified_data), |
11242 |
STRING_BYTES (XSTRING (specified_data))); |
SBYTES (specified_data)); |
11243 |
|
|
11244 |
jpeg_read_header (&cinfo, TRUE); |
fn_jpeg_read_header (&cinfo, TRUE); |
11245 |
|
|
11246 |
/* Customize decompression so that color quantization will be used. |
/* Customize decompression so that color quantization will be used. |
11247 |
Start decompression. */ |
Start decompression. */ |
11248 |
cinfo.quantize_colors = TRUE; |
cinfo.quantize_colors = TRUE; |
11249 |
jpeg_start_decompress (&cinfo); |
fn_jpeg_start_decompress (&cinfo); |
11250 |
width = img->width = cinfo.output_width; |
width = img->width = cinfo.output_width; |
11251 |
height = img->height = cinfo.output_height; |
height = img->height = cinfo.output_height; |
11252 |
|
|
11253 |
/* Create X image and pixmap. */ |
/* Create X image and pixmap. */ |
11254 |
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, |
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) |
|
&img->pixmap)) |
|
11255 |
longjmp (mgr.setjmp_buffer, 2); |
longjmp (mgr.setjmp_buffer, 2); |
11256 |
|
|
11257 |
/* Allocate colors. When color quantization is used, |
/* Allocate colors. When color quantization is used, |
11269 |
else |
else |
11270 |
ir = 0, ig = 0, ib = 0; |
ir = 0, ig = 0, ib = 0; |
11271 |
|
|
11272 |
|
#if 0 /* TODO: Color tables. */ |
11273 |
/* Use the color table mechanism because it handles colors that |
/* Use the color table mechanism because it handles colors that |
11274 |
cannot be allocated nicely. Such colors will be replaced with |
cannot be allocated nicely. Such colors will be replaced with |
11275 |
a default color, and we don't have to care about which colors |
a default color, and we don't have to care about which colors |
11276 |
can be freed safely, and which can't. */ |
can be freed safely, and which can't. */ |
11277 |
init_color_table (); |
init_color_table (); |
11278 |
|
#endif |
11279 |
colors = (unsigned long *) alloca (cinfo.actual_number_of_colors |
colors = (unsigned long *) alloca (cinfo.actual_number_of_colors |
11280 |
* sizeof *colors); |
* sizeof *colors); |
11281 |
|
|
11282 |
for (i = 0; i < cinfo.actual_number_of_colors; ++i) |
for (i = 0; i < cinfo.actual_number_of_colors; ++i) |
11283 |
{ |
{ |
11284 |
/* Multiply RGB values with 255 because X expects RGB values |
int r = cinfo.colormap[ir][i]; |
11285 |
in the range 0..0xffff. */ |
int g = cinfo.colormap[ig][i]; |
11286 |
int r = cinfo.colormap[ir][i] << 8; |
int b = cinfo.colormap[ib][i]; |
11287 |
int g = cinfo.colormap[ig][i] << 8; |
#if 0 /* TODO: Color tables. */ |
|
int b = cinfo.colormap[ib][i] << 8; |
|
11288 |
colors[i] = lookup_rgb_color (f, r, g, b); |
colors[i] = lookup_rgb_color (f, r, g, b); |
11289 |
|
#else |
11290 |
|
colors[i] = PALETTERGB (r, g, b); |
11291 |
|
#endif |
11292 |
} |
} |
11293 |
|
|
11294 |
|
#if 0 /* TODO: Color tables. */ |
11295 |
/* Remember those colors actually allocated. */ |
/* Remember those colors actually allocated. */ |
11296 |
img->colors = colors_in_color_table (&img->ncolors); |
img->colors = colors_in_color_table (&img->ncolors); |
11297 |
free_color_table (); |
free_color_table (); |
11298 |
|
#endif |
11299 |
} |
} |
11300 |
|
|
11301 |
/* Read pixels. */ |
/* Read pixels. */ |
11304 |
row_stride, 1); |
row_stride, 1); |
11305 |
for (y = 0; y < height; ++y) |
for (y = 0; y < height; ++y) |
11306 |
{ |
{ |
11307 |
jpeg_read_scanlines (&cinfo, buffer, 1); |
fn_jpeg_read_scanlines (&cinfo, buffer, 1); |
11308 |
for (x = 0; x < cinfo.output_width; ++x) |
for (x = 0; x < cinfo.output_width; ++x) |
11309 |
XPutPixel (ximg, x, y, colors[buffer[0][x]]); |
XPutPixel (ximg, x, y, colors[buffer[0][x]]); |
11310 |
} |
} |
11311 |
|
|
11312 |
/* Clean up. */ |
/* Clean up. */ |
11313 |
jpeg_finish_decompress (&cinfo); |
fn_jpeg_finish_decompress (&cinfo); |
11314 |
jpeg_destroy_decompress (&cinfo); |
fn_jpeg_destroy_decompress (&cinfo); |
11315 |
if (fp) |
if (fp) |
11316 |
fclose (fp); |
fclose ((FILE *) fp); |
11317 |
|
|
11318 |
/* Maybe fill in the background field while we have ximg handy. */ |
/* Maybe fill in the background field while we have ximg handy. */ |
11319 |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
11320 |
IMAGE_BACKGROUND (img, f, ximg); |
IMAGE_BACKGROUND (img, f, ximg); |
11321 |
|
|
11322 |
/* Put the image into the pixmap. */ |
/* Put the image into the pixmap. */ |
11323 |
x_put_x_image (f, ximg, img->pixmap, width, height); |
x_put_x_image (f, ximg, img->pixmap, width, height); |
11324 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
|
UNBLOCK_INPUT; |
|
11325 |
UNGCPRO; |
UNGCPRO; |
11326 |
return 1; |
return 1; |
11327 |
} |
} |
11370 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
11371 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
11372 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
11373 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
11374 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
11375 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
11376 |
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
11390 |
NULL |
NULL |
11391 |
}; |
}; |
11392 |
|
|
11393 |
|
/* TIFF library details. */ |
11394 |
|
DEF_IMGLIB_FN (TIFFSetErrorHandler); |
11395 |
|
DEF_IMGLIB_FN (TIFFSetWarningHandler); |
11396 |
|
DEF_IMGLIB_FN (TIFFOpen); |
11397 |
|
DEF_IMGLIB_FN (TIFFClientOpen); |
11398 |
|
DEF_IMGLIB_FN (TIFFGetField); |
11399 |
|
DEF_IMGLIB_FN (TIFFReadRGBAImage); |
11400 |
|
DEF_IMGLIB_FN (TIFFClose); |
11401 |
|
|
11402 |
|
static int |
11403 |
|
init_tiff_functions (library) |
11404 |
|
HMODULE library; |
11405 |
|
{ |
11406 |
|
LOAD_IMGLIB_FN (library, TIFFSetErrorHandler); |
11407 |
|
LOAD_IMGLIB_FN (library, TIFFSetWarningHandler); |
11408 |
|
LOAD_IMGLIB_FN (library, TIFFOpen); |
11409 |
|
LOAD_IMGLIB_FN (library, TIFFClientOpen); |
11410 |
|
LOAD_IMGLIB_FN (library, TIFFGetField); |
11411 |
|
LOAD_IMGLIB_FN (library, TIFFReadRGBAImage); |
11412 |
|
LOAD_IMGLIB_FN (library, TIFFClose); |
11413 |
|
return 1; |
11414 |
|
} |
11415 |
|
|
11416 |
/* Return non-zero if OBJECT is a valid TIFF image specification. */ |
/* Return non-zero if OBJECT is a valid TIFF image specification. */ |
11417 |
|
|
11421 |
{ |
{ |
11422 |
struct image_keyword fmt[TIFF_LAST]; |
struct image_keyword fmt[TIFF_LAST]; |
11423 |
bcopy (tiff_format, fmt, sizeof fmt); |
bcopy (tiff_format, fmt, sizeof fmt); |
11424 |
|
|
11425 |
if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff) |
if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff)) |
|
|| (fmt[TIFF_ASCENT].count |
|
|
&& XFASTINT (fmt[TIFF_ASCENT].value) > 100)) |
|
11426 |
return 0; |
return 0; |
11427 |
|
|
11428 |
/* Must specify either the :data or :file keyword. */ |
/* Must specify either the :data or :file keyword. */ |
11429 |
return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; |
return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1; |
11430 |
} |
} |
11485 |
case SEEK_SET: /* Go from beginning of source. */ |
case SEEK_SET: /* Go from beginning of source. */ |
11486 |
idx = off; |
idx = off; |
11487 |
break; |
break; |
11488 |
|
|
11489 |
case SEEK_END: /* Go from end of source. */ |
case SEEK_END: /* Go from end of source. */ |
11490 |
idx = src->len + off; |
idx = src->len + off; |
11491 |
break; |
break; |
11492 |
|
|
11493 |
case SEEK_CUR: /* Go from current position. */ |
case SEEK_CUR: /* Go from current position. */ |
11494 |
idx = src->index + off; |
idx = src->index + off; |
11495 |
break; |
break; |
11496 |
|
|
11497 |
default: /* Invalid `whence'. */ |
default: /* Invalid `whence'. */ |
11498 |
return -1; |
return -1; |
11499 |
} |
} |
11500 |
|
|
11501 |
if (idx > src->len || idx < 0) |
if (idx > src->len || idx < 0) |
11502 |
return -1; |
return -1; |
11503 |
|
|
11504 |
src->index = idx; |
src->index = idx; |
11505 |
return src->index; |
return src->index; |
11506 |
} |
} |
11547 |
{ |
{ |
11548 |
char buf[512]; |
char buf[512]; |
11549 |
int len; |
int len; |
11550 |
|
|
11551 |
len = sprintf (buf, "TIFF error: %s ", title); |
len = sprintf (buf, "TIFF error: %s ", title); |
11552 |
vsprintf (buf + len, format, ap); |
vsprintf (buf + len, format, ap); |
11553 |
add_to_log (buf, Qnil, Qnil); |
add_to_log (buf, Qnil, Qnil); |
11561 |
{ |
{ |
11562 |
char buf[512]; |
char buf[512]; |
11563 |
int len; |
int len; |
11564 |
|
|
11565 |
len = sprintf (buf, "TIFF warning: %s ", title); |
len = sprintf (buf, "TIFF warning: %s ", title); |
11566 |
vsprintf (buf + len, format, ap); |
vsprintf (buf + len, format, ap); |
11567 |
add_to_log (buf, Qnil, Qnil); |
add_to_log (buf, Qnil, Qnil); |
11591 |
file = Qnil; |
file = Qnil; |
11592 |
GCPRO1 (file); |
GCPRO1 (file); |
11593 |
|
|
11594 |
TIFFSetErrorHandler (tiff_error_handler); |
fn_TIFFSetErrorHandler (tiff_error_handler); |
11595 |
TIFFSetWarningHandler (tiff_warning_handler); |
fn_TIFFSetWarningHandler (tiff_warning_handler); |
11596 |
|
|
11597 |
if (NILP (specified_data)) |
if (NILP (specified_data)) |
11598 |
{ |
{ |
11604 |
UNGCPRO; |
UNGCPRO; |
11605 |
return 0; |
return 0; |
11606 |
} |
} |
11607 |
|
|
11608 |
/* Try to open the image file. */ |
/* Try to open the image file. */ |
11609 |
tiff = TIFFOpen (XSTRING (file)->data, "r"); |
tiff = fn_TIFFOpen (SDATA (file), "r"); |
11610 |
if (tiff == NULL) |
if (tiff == NULL) |
11611 |
{ |
{ |
11612 |
image_error ("Cannot open `%s'", file, Qnil); |
image_error ("Cannot open `%s'", file, Qnil); |
11617 |
else |
else |
11618 |
{ |
{ |
11619 |
/* Memory source! */ |
/* Memory source! */ |
11620 |
memsrc.bytes = XSTRING (specified_data)->data; |
memsrc.bytes = SDATA (specified_data); |
11621 |
memsrc.len = STRING_BYTES (XSTRING (specified_data)); |
memsrc.len = SBYTES (specified_data); |
11622 |
memsrc.index = 0; |
memsrc.index = 0; |
11623 |
|
|
11624 |
tiff = TIFFClientOpen ("memory_source", "r", &memsrc, |
tiff = fn_TIFFClientOpen ("memory_source", "r", &memsrc, |
11625 |
(TIFFReadWriteProc) tiff_read_from_memory, |
(TIFFReadWriteProc) tiff_read_from_memory, |
11626 |
(TIFFReadWriteProc) tiff_write_from_memory, |
(TIFFReadWriteProc) tiff_write_from_memory, |
11627 |
tiff_seek_in_memory, |
tiff_seek_in_memory, |
11628 |
tiff_close_memory, |
tiff_close_memory, |
11629 |
tiff_size_of_memory, |
tiff_size_of_memory, |
11630 |
tiff_mmap_memory, |
tiff_mmap_memory, |
11631 |
tiff_unmap_memory); |
tiff_unmap_memory); |
11632 |
|
|
11633 |
if (!tiff) |
if (!tiff) |
11634 |
{ |
{ |
11640 |
|
|
11641 |
/* Get width and height of the image, and allocate a raster buffer |
/* Get width and height of the image, and allocate a raster buffer |
11642 |
of width x height 32-bit values. */ |
of width x height 32-bit values. */ |
11643 |
TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); |
fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); |
11644 |
TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); |
fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); |
11645 |
buf = (uint32 *) xmalloc (width * height * sizeof *buf); |
buf = (uint32 *) xmalloc (width * height * sizeof *buf); |
11646 |
|
|
11647 |
rc = TIFFReadRGBAImage (tiff, width, height, buf, 0); |
rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); |
11648 |
TIFFClose (tiff); |
fn_TIFFClose (tiff); |
11649 |
if (!rc) |
if (!rc) |
11650 |
{ |
{ |
11651 |
image_error ("Error reading TIFF image `%s'", img->spec, Qnil); |
image_error ("Error reading TIFF image `%s'", img->spec, Qnil); |
11662 |
return 0; |
return 0; |
11663 |
} |
} |
11664 |
|
|
11665 |
|
#if 0 /* TODO: Color tables. */ |
11666 |
/* Initialize the color table. */ |
/* Initialize the color table. */ |
11667 |
init_color_table (); |
init_color_table (); |
11668 |
|
#endif |
11669 |
|
|
11670 |
/* Process the pixel raster. Origin is in the lower-left corner. */ |
/* Process the pixel raster. Origin is in the lower-left corner. */ |
11671 |
for (y = 0; y < height; ++y) |
for (y = 0; y < height; ++y) |
11672 |
{ |
{ |
11673 |
uint32 *row = buf + y * width; |
uint32 *row = buf + y * width; |
11674 |
|
|
11675 |
for (x = 0; x < width; ++x) |
for (x = 0; x < width; ++x) |
11676 |
{ |
{ |
11677 |
uint32 abgr = row[x]; |
uint32 abgr = row[x]; |
11678 |
int r = TIFFGetR (abgr) << 8; |
int r = TIFFGetR (abgr); |
11679 |
int g = TIFFGetG (abgr) << 8; |
int g = TIFFGetG (abgr); |
11680 |
int b = TIFFGetB (abgr) << 8; |
int b = TIFFGetB (abgr); |
11681 |
XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); |
#if 0 /* TODO: Color tables. */ |
11682 |
|
XPutPixel (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b)); |
11683 |
|
#else |
11684 |
|
XPutPixel (ximg, x, height - 1 - y, PALETTERGB (r, g, b)); |
11685 |
|
#endif |
11686 |
} |
} |
11687 |
} |
} |
11688 |
|
|
11689 |
|
#if 0 /* TODO: Color tables. */ |
11690 |
/* Remember the colors allocated for the image. Free the color table. */ |
/* Remember the colors allocated for the image. Free the color table. */ |
11691 |
img->colors = colors_in_color_table (&img->ncolors); |
img->colors = colors_in_color_table (&img->ncolors); |
11692 |
free_color_table (); |
free_color_table (); |
11693 |
|
#endif |
11694 |
|
|
11695 |
img->width = width; |
img->width = width; |
11696 |
img->height = height; |
img->height = height; |
11718 |
|
|
11719 |
#if HAVE_GIF |
#if HAVE_GIF |
11720 |
|
|
11721 |
|
#define DrawText gif_DrawText |
11722 |
#include <gif_lib.h> |
#include <gif_lib.h> |
11723 |
|
#undef DrawText |
11724 |
|
|
11725 |
static int gif_image_p P_ ((Lisp_Object object)); |
static int gif_image_p P_ ((Lisp_Object object)); |
11726 |
static int gif_load P_ ((struct frame *f, struct image *img)); |
static int gif_load P_ ((struct frame *f, struct image *img)); |
11755 |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
{":type", IMAGE_SYMBOL_VALUE, 1}, |
11756 |
{":data", IMAGE_STRING_VALUE, 0}, |
{":data", IMAGE_STRING_VALUE, 0}, |
11757 |
{":file", IMAGE_STRING_VALUE, 0}, |
{":file", IMAGE_STRING_VALUE, 0}, |
11758 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
11759 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
11760 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
11761 |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
11776 |
NULL |
NULL |
11777 |
}; |
}; |
11778 |
|
|
11779 |
|
|
11780 |
|
/* GIF library details. */ |
11781 |
|
DEF_IMGLIB_FN (DGifCloseFile); |
11782 |
|
DEF_IMGLIB_FN (DGifSlurp); |
11783 |
|
DEF_IMGLIB_FN (DGifOpen); |
11784 |
|
DEF_IMGLIB_FN (DGifOpenFileName); |
11785 |
|
|
11786 |
|
static int |
11787 |
|
init_gif_functions (library) |
11788 |
|
HMODULE library; |
11789 |
|
{ |
11790 |
|
LOAD_IMGLIB_FN (library, DGifCloseFile); |
11791 |
|
LOAD_IMGLIB_FN (library, DGifSlurp); |
11792 |
|
LOAD_IMGLIB_FN (library, DGifOpen); |
11793 |
|
LOAD_IMGLIB_FN (library, DGifOpenFileName); |
11794 |
|
return 1; |
11795 |
|
} |
11796 |
|
|
11797 |
|
|
11798 |
/* Return non-zero if OBJECT is a valid GIF image specification. */ |
/* Return non-zero if OBJECT is a valid GIF image specification. */ |
11799 |
|
|
11800 |
static int |
static int |
11803 |
{ |
{ |
11804 |
struct image_keyword fmt[GIF_LAST]; |
struct image_keyword fmt[GIF_LAST]; |
11805 |
bcopy (gif_format, fmt, sizeof fmt); |
bcopy (gif_format, fmt, sizeof fmt); |
11806 |
|
|
11807 |
if (!parse_image_spec (object, fmt, GIF_LAST, Qgif) |
if (!parse_image_spec (object, fmt, GIF_LAST, Qgif)) |
|
|| (fmt[GIF_ASCENT].count |
|
|
&& XFASTINT (fmt[GIF_ASCENT].value) > 100)) |
|
11808 |
return 0; |
return 0; |
11809 |
|
|
11810 |
/* Must specify either the :data or :file keyword. */ |
/* Must specify either the :data or :file keyword. */ |
11811 |
return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; |
return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1; |
11812 |
} |
} |
11879 |
UNGCPRO; |
UNGCPRO; |
11880 |
return 0; |
return 0; |
11881 |
} |
} |
11882 |
|
|
11883 |
/* Open the GIF file. */ |
/* Open the GIF file. */ |
11884 |
gif = DGifOpenFileName (XSTRING (file)->data); |
gif = fn_DGifOpenFileName (SDATA (file)); |
11885 |
if (gif == NULL) |
if (gif == NULL) |
11886 |
{ |
{ |
11887 |
image_error ("Cannot open `%s'", file, Qnil); |
image_error ("Cannot open `%s'", file, Qnil); |
11893 |
{ |
{ |
11894 |
/* Read from memory! */ |
/* Read from memory! */ |
11895 |
current_gif_memory_src = &memsrc; |
current_gif_memory_src = &memsrc; |
11896 |
memsrc.bytes = XSTRING (specified_data)->data; |
memsrc.bytes = SDATA (specified_data); |
11897 |
memsrc.len = STRING_BYTES (XSTRING (specified_data)); |
memsrc.len = SBYTES (specified_data); |
11898 |
memsrc.index = 0; |
memsrc.index = 0; |
11899 |
|
|
11900 |
gif = DGifOpen(&memsrc, gif_read_from_memory); |
gif = fn_DGifOpen(&memsrc, gif_read_from_memory); |
11901 |
if (!gif) |
if (!gif) |
11902 |
{ |
{ |
11903 |
image_error ("Cannot open memory source `%s'", img->spec, Qnil); |
image_error ("Cannot open memory source `%s'", img->spec, Qnil); |
11907 |
} |
} |
11908 |
|
|
11909 |
/* Read entire contents. */ |
/* Read entire contents. */ |
11910 |
rc = DGifSlurp (gif); |
rc = fn_DGifSlurp (gif); |
11911 |
if (rc == GIF_ERROR) |
if (rc == GIF_ERROR) |
11912 |
{ |
{ |
11913 |
image_error ("Error reading `%s'", img->spec, Qnil); |
image_error ("Error reading `%s'", img->spec, Qnil); |
11914 |
DGifCloseFile (gif); |
fn_DGifCloseFile (gif); |
11915 |
UNGCPRO; |
UNGCPRO; |
11916 |
return 0; |
return 0; |
11917 |
} |
} |
11922 |
{ |
{ |
11923 |
image_error ("Invalid image number `%s' in image `%s'", |
image_error ("Invalid image number `%s' in image `%s'", |
11924 |
image, img->spec); |
image, img->spec); |
11925 |
DGifCloseFile (gif); |
fn_DGifCloseFile (gif); |
11926 |
UNGCPRO; |
UNGCPRO; |
11927 |
return 0; |
return 0; |
11928 |
} |
} |
11929 |
|
|
11930 |
width = img->width = gif->SWidth; |
width = img->width = max (gif->SWidth, gif->Image.Left + gif->Image.Width); |
11931 |
height = img->height = gif->SHeight; |
height = img->height = max (gif->SHeight, gif->Image.Top + gif->Image.Height); |
11932 |
|
|
11933 |
/* Create the X image and pixmap. */ |
/* Create the X image and pixmap. */ |
11934 |
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)) |
11935 |
{ |
{ |
11936 |
DGifCloseFile (gif); |
fn_DGifCloseFile (gif); |
11937 |
UNGCPRO; |
UNGCPRO; |
11938 |
return 0; |
return 0; |
11939 |
} |
} |
11940 |
|
|
11941 |
/* Allocate colors. */ |
/* Allocate colors. */ |
11942 |
gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap; |
gif_color_map = gif->SavedImages[ino].ImageDesc.ColorMap; |
11943 |
if (!gif_color_map) |
if (!gif_color_map) |
11944 |
gif_color_map = gif->SColorMap; |
gif_color_map = gif->SColorMap; |
11945 |
|
#if 0 /* TODO: Color tables */ |
11946 |
init_color_table (); |
init_color_table (); |
11947 |
|
#endif |
11948 |
bzero (pixel_colors, sizeof pixel_colors); |
bzero (pixel_colors, sizeof pixel_colors); |
11949 |
|
|
11950 |
for (i = 0; i < gif_color_map->ColorCount; ++i) |
for (i = 0; i < gif_color_map->ColorCount; ++i) |
11951 |
{ |
{ |
11952 |
int r = gif_color_map->Colors[i].Red << 8; |
int r = gif_color_map->Colors[i].Red; |
11953 |
int g = gif_color_map->Colors[i].Green << 8; |
int g = gif_color_map->Colors[i].Green; |
11954 |
int b = gif_color_map->Colors[i].Blue << 8; |
int b = gif_color_map->Colors[i].Blue; |
11955 |
|
#if 0 /* TODO: Color tables */ |
11956 |
pixel_colors[i] = lookup_rgb_color (f, r, g, b); |
pixel_colors[i] = lookup_rgb_color (f, r, g, b); |
11957 |
|
#else |
11958 |
|
pixel_colors[i] = PALETTERGB (r, g, b); |
11959 |
|
#endif |
11960 |
} |
} |
11961 |
|
|
11962 |
|
#if 0 /* TODO: Color tables */ |
11963 |
img->colors = colors_in_color_table (&img->ncolors); |
img->colors = colors_in_color_table (&img->ncolors); |
11964 |
free_color_table (); |
free_color_table (); |
11965 |
|
#endif |
11966 |
|
|
11967 |
/* Clear the part of the screen image that are not covered by |
/* Clear the part of the screen image that are not covered by |
11968 |
the image from the GIF file. Full animated GIF support |
the image from the GIF file. Full animated GIF support |
11969 |
requires more than can be done here (see the gif89 spec, |
requires more than can be done here (see the gif89 spec, |
11970 |
disposal methods). Let's simply assume that the part |
disposal methods). Let's simply assume that the part |
11971 |
not covered by a sub-image is in the frame's background color. */ |
not covered by a sub-image is in the frame's background color. */ |
12012 |
while (row >= image_height) |
while (row >= image_height) |
12013 |
row = interlace_start[++pass]; |
row = interlace_start[++pass]; |
12014 |
} |
} |
12015 |
|
|
12016 |
for (x = 0; x < image_width; x++) |
for (x = 0; x < image_width; x++) |
12017 |
{ |
{ |
12018 |
int i = raster[(y * image_width) + x]; |
int i = raster[(y * image_width) + x]; |
12019 |
XPutPixel (ximg, x + image_left, row + image_top, |
XPutPixel (ximg, x + image_left, row + image_top, |
12020 |
pixel_colors[i]); |
pixel_colors[i]); |
12021 |
} |
} |
12022 |
|
|
12023 |
row += interlace_increment[pass]; |
row += interlace_increment[pass]; |
12024 |
} |
} |
12025 |
} |
} |
12032 |
XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); |
XPutPixel (ximg, x + image_left, y + image_top, pixel_colors[i]); |
12033 |
} |
} |
12034 |
} |
} |
12035 |
|
|
12036 |
DGifCloseFile (gif); |
fn_DGifCloseFile (gif); |
12037 |
|
|
12038 |
/* Maybe fill in the background field while we have ximg handy. */ |
/* Maybe fill in the background field while we have ximg handy. */ |
12039 |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
12042 |
/* Put the image into the pixmap, then free the X image and its buffer. */ |
/* Put the image into the pixmap, then free the X image and its buffer. */ |
12043 |
x_put_x_image (f, ximg, img->pixmap, width, height); |
x_put_x_image (f, ximg, img->pixmap, width, height); |
12044 |
x_destroy_x_image (ximg); |
x_destroy_x_image (ximg); |
12045 |
|
|
12046 |
UNGCPRO; |
UNGCPRO; |
12047 |
return 1; |
return 1; |
12048 |
} |
} |
12057 |
|
|
12058 |
Lisp_Object Qpostscript; |
Lisp_Object Qpostscript; |
12059 |
|
|
12060 |
|
/* Keyword symbols. */ |
12061 |
|
|
12062 |
|
Lisp_Object QCloader, QCbounding_box, QCpt_width, QCpt_height; |
12063 |
|
|
12064 |
#ifdef HAVE_GHOSTSCRIPT |
#ifdef HAVE_GHOSTSCRIPT |
12065 |
static int gs_image_p P_ ((Lisp_Object object)); |
static int gs_image_p P_ ((Lisp_Object object)); |
12066 |
static int gs_load P_ ((struct frame *f, struct image *img)); |
static int gs_load P_ ((struct frame *f, struct image *img)); |
12103 |
{":file", IMAGE_STRING_VALUE, 1}, |
{":file", IMAGE_STRING_VALUE, 1}, |
12104 |
{":loader", IMAGE_FUNCTION_VALUE, 0}, |
{":loader", IMAGE_FUNCTION_VALUE, 0}, |
12105 |
{":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, |
{":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1}, |
12106 |
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
{":ascent", IMAGE_ASCENT_VALUE, 0}, |
12107 |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0}, |
12108 |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
{":relief", IMAGE_INTEGER_VALUE, 0}, |
12109 |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0}, |
12147 |
struct image_keyword fmt[GS_LAST]; |
struct image_keyword fmt[GS_LAST]; |
12148 |
Lisp_Object tem; |
Lisp_Object tem; |
12149 |
int i; |
int i; |
12150 |
|
|
12151 |
bcopy (gs_format, fmt, sizeof fmt); |
bcopy (gs_format, fmt, sizeof fmt); |
12152 |
|
|
12153 |
if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript) |
if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript)) |
|
|| (fmt[GS_ASCENT].count |
|
|
&& XFASTINT (fmt[GS_ASCENT].value) > 100)) |
|
12154 |
return 0; |
return 0; |
12155 |
|
|
12156 |
/* Bounding box must be a list or vector containing 4 integers. */ |
/* Bounding box must be a list or vector containing 4 integers. */ |
12217 |
image_error ("Unable to create pixmap for `%s'", img->spec, Qnil); |
image_error ("Unable to create pixmap for `%s'", img->spec, Qnil); |
12218 |
return 0; |
return 0; |
12219 |
} |
} |
12220 |
|
|
12221 |
/* Call the loader to fill the pixmap. It returns a process object |
/* Call the loader to fill the pixmap. It returns a process object |
12222 |
if successful. We do not record_unwind_protect here because |
if successful. We do not record_unwind_protect here because |
12223 |
other places in redisplay like calling window scroll functions |
other places in redisplay like calling window scroll functions |
12228 |
(unsigned long) FRAME_W32_WINDOW (f), |
(unsigned long) FRAME_W32_WINDOW (f), |
12229 |
(unsigned long) img->pixmap); |
(unsigned long) img->pixmap); |
12230 |
window_and_pixmap_id = build_string (buffer); |
window_and_pixmap_id = build_string (buffer); |
12231 |
|
|
12232 |
sprintf (buffer, "%lu %lu", |
sprintf (buffer, "%lu %lu", |
12233 |
FRAME_FOREGROUND_PIXEL (f), |
FRAME_FOREGROUND_PIXEL (f), |
12234 |
FRAME_BACKGROUND_PIXEL (f)); |
FRAME_BACKGROUND_PIXEL (f)); |
12235 |
pixel_colors = build_string (buffer); |
pixel_colors = build_string (buffer); |
12236 |
|
|
12237 |
XSETFRAME (frame, f); |
XSETFRAME (frame, f); |
12238 |
loader = image_spec_value (img->spec, QCloader, NULL); |
loader = image_spec_value (img->spec, QCloader, NULL); |
12239 |
if (NILP (loader)) |
if (NILP (loader)) |
12295 |
if (ximg) |
if (ximg) |
12296 |
{ |
{ |
12297 |
int x, y; |
int x, y; |
12298 |
|
|
12299 |
/* Initialize the color table. */ |
/* Initialize the color table. */ |
12300 |
init_color_table (); |
init_color_table (); |
12301 |
|
|
12302 |
/* For each pixel of the image, look its color up in the |
/* For each pixel of the image, look its color up in the |
12303 |
color table. After having done so, the color table will |
color table. After having done so, the color table will |
12304 |
contain an entry for each color used by the image. */ |
contain an entry for each color used by the image. */ |
12328 |
else |
else |
12329 |
image_error ("Cannot get X image of `%s'; colors will not be freed", |
image_error ("Cannot get X image of `%s'; colors will not be freed", |
12330 |
img->spec, Qnil); |
img->spec, Qnil); |
12331 |
|
|
12332 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
12333 |
} |
} |
12334 |
|
|
12362 |
CHECK_STRING (value); |
CHECK_STRING (value); |
12363 |
|
|
12364 |
BLOCK_INPUT; |
BLOCK_INPUT; |
12365 |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False); |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False); |
12366 |
XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
XChangeProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
12367 |
prop_atom, XA_STRING, 8, PropModeReplace, |
prop_atom, XA_STRING, 8, PropModeReplace, |
12368 |
XSTRING (value)->data, XSTRING (value)->size); |
SDATA (value), SCHARS (value)); |
12369 |
|
|
12370 |
/* Make sure the property is set when we return. */ |
/* Make sure the property is set when we return. */ |
12371 |
XFlush (FRAME_W32_DISPLAY (f)); |
XFlush (FRAME_W32_DISPLAY (f)); |
12391 |
|
|
12392 |
CHECK_STRING (prop); |
CHECK_STRING (prop); |
12393 |
BLOCK_INPUT; |
BLOCK_INPUT; |
12394 |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False); |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False); |
12395 |
XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom); |
XDeleteProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), prop_atom); |
12396 |
|
|
12397 |
/* Make sure the property is removed when we return. */ |
/* Make sure the property is removed when we return. */ |
12425 |
|
|
12426 |
CHECK_STRING (prop); |
CHECK_STRING (prop); |
12427 |
BLOCK_INPUT; |
BLOCK_INPUT; |
12428 |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), XSTRING (prop)->data, False); |
prop_atom = XInternAtom (FRAME_W32_DISPLAY (f), SDATA (prop), False); |
12429 |
rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
12430 |
prop_atom, 0, 0, False, XA_STRING, |
prop_atom, 0, 0, False, XA_STRING, |
12431 |
&actual_type, &actual_format, &actual_size, |
&actual_type, &actual_format, &actual_size, |
12440 |
rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
rc = XGetWindowProperty (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f), |
12441 |
prop_atom, 0, bytes_remaining, |
prop_atom, 0, bytes_remaining, |
12442 |
False, XA_STRING, |
False, XA_STRING, |
12443 |
&actual_type, &actual_format, |
&actual_type, &actual_format, |
12444 |
&actual_size, &bytes_remaining, |
&actual_size, &bytes_remaining, |
12445 |
(unsigned char **) &tmp_data); |
(unsigned char **) &tmp_data); |
12446 |
if (rc == Success) |
if (rc == Success) |
12447 |
prop_value = make_string (tmp_data, size); |
prop_value = make_string (tmp_data, size); |
12495 |
#if 0 /* TODO: cursor shape changes. */ |
#if 0 /* TODO: cursor shape changes. */ |
12496 |
EMACS_TIME delay; |
EMACS_TIME delay; |
12497 |
int secs, usecs = 0; |
int secs, usecs = 0; |
12498 |
|
|
12499 |
cancel_hourglass (); |
cancel_hourglass (); |
12500 |
|
|
12501 |
if (INTEGERP (Vhourglass_delay) |
if (INTEGERP (Vhourglass_delay) |
12511 |
} |
} |
12512 |
else |
else |
12513 |
secs = DEFAULT_HOURGLASS_DELAY; |
secs = DEFAULT_HOURGLASS_DELAY; |
12514 |
|
|
12515 |
EMACS_SET_SECS_USECS (delay, secs, usecs); |
EMACS_SET_SECS_USECS (delay, secs, usecs); |
12516 |
hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, |
hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, |
12517 |
show_hourglass, NULL); |
show_hourglass, NULL); |
12530 |
cancel_atimer (hourglass_atimer); |
cancel_atimer (hourglass_atimer); |
12531 |
hourglass_atimer = NULL; |
hourglass_atimer = NULL; |
12532 |
} |
} |
12533 |
|
|
12534 |
if (hourglass_shown_p) |
if (hourglass_shown_p) |
12535 |
hide_hourglass (); |
hide_hourglass (); |
12536 |
} |
} |
12557 |
if (!hourglass_shown_p) |
if (!hourglass_shown_p) |
12558 |
{ |
{ |
12559 |
Lisp_Object rest, frame; |
Lisp_Object rest, frame; |
12560 |
|
|
12561 |
BLOCK_INPUT; |
BLOCK_INPUT; |
12562 |
|
|
12563 |
FOR_EACH_FRAME (rest, frame) |
FOR_EACH_FRAME (rest, frame) |
12564 |
if (FRAME_W32_P (XFRAME (frame))) |
if (FRAME_W32_P (XFRAME (frame))) |
12565 |
{ |
{ |
12566 |
struct frame *f = XFRAME (frame); |
struct frame *f = XFRAME (frame); |
12567 |
|
|
12568 |
f->output_data.w32->hourglass_p = 1; |
f->output_data.w32->hourglass_p = 1; |
12569 |
|
|
12570 |
if (!f->output_data.w32->hourglass_window) |
if (!f->output_data.w32->hourglass_window) |
12571 |
{ |
{ |
12572 |
unsigned long mask = CWCursor; |
unsigned long mask = CWCursor; |
12573 |
XSetWindowAttributes attrs; |
XSetWindowAttributes attrs; |
12574 |
|
|
12575 |
attrs.cursor = f->output_data.w32->hourglass_cursor; |
attrs.cursor = f->output_data.w32->hourglass_cursor; |
12576 |
|
|
12577 |
f->output_data.w32->hourglass_window |
f->output_data.w32->hourglass_window |
12578 |
= XCreateWindow (FRAME_X_DISPLAY (f), |
= XCreateWindow (FRAME_X_DISPLAY (f), |
12579 |
FRAME_OUTER_WINDOW (f), |
FRAME_OUTER_WINDOW (f), |
12582 |
CopyFromParent, |
CopyFromParent, |
12583 |
mask, &attrs); |
mask, &attrs); |
12584 |
} |
} |
12585 |
|
|
12586 |
XMapRaised (FRAME_X_DISPLAY (f), |
XMapRaised (FRAME_X_DISPLAY (f), |
12587 |
f->output_data.w32->hourglass_window); |
f->output_data.w32->hourglass_window); |
12588 |
XFlush (FRAME_X_DISPLAY (f)); |
XFlush (FRAME_X_DISPLAY (f)); |
12609 |
FOR_EACH_FRAME (rest, frame) |
FOR_EACH_FRAME (rest, frame) |
12610 |
{ |
{ |
12611 |
struct frame *f = XFRAME (frame); |
struct frame *f = XFRAME (frame); |
12612 |
|
|
12613 |
if (FRAME_W32_P (f) |
if (FRAME_W32_P (f) |
12614 |
/* Watch out for newly created frames. */ |
/* Watch out for newly created frames. */ |
12615 |
&& f->output_data.x->hourglass_window) |
&& f->output_data.x->hourglass_window) |
12639 |
Lisp_Object, Lisp_Object)); |
Lisp_Object, Lisp_Object)); |
12640 |
static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, |
static void compute_tip_xy P_ ((struct frame *, Lisp_Object, Lisp_Object, |
12641 |
Lisp_Object, int, int, int *, int *)); |
Lisp_Object, int, int, int *, int *)); |
12642 |
|
|
12643 |
/* The frame of a currently visible tooltip. */ |
/* The frame of a currently visible tooltip. */ |
12644 |
|
|
12645 |
Lisp_Object tip_frame; |
Lisp_Object tip_frame; |
12672 |
tip_window = NULL; |
tip_window = NULL; |
12673 |
tip_frame = Qnil; |
tip_frame = Qnil; |
12674 |
} |
} |
12675 |
|
|
12676 |
return deleted; |
return deleted; |
12677 |
} |
} |
12678 |
|
|
12696 |
Lisp_Object name; |
Lisp_Object name; |
12697 |
long window_prompting = 0; |
long window_prompting = 0; |
12698 |
int width, height; |
int width, height; |
12699 |
int count = BINDING_STACK_SIZE (); |
int count = SPECPDL_INDEX (); |
12700 |
struct gcpro gcpro1, gcpro2, gcpro3; |
struct gcpro gcpro1, gcpro2, gcpro3; |
12701 |
struct kboard *kb; |
struct kboard *kb; |
12702 |
int face_change_count_before = face_change_count; |
int face_change_count_before = face_change_count; |
12738 |
Ferase_buffer (); |
Ferase_buffer (); |
12739 |
Finsert (1, &text); |
Finsert (1, &text); |
12740 |
set_buffer_internal_1 (old_buffer); |
set_buffer_internal_1 (old_buffer); |
12741 |
|
|
12742 |
FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; |
FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; |
12743 |
record_unwind_protect (unwind_create_tip_frame, frame); |
record_unwind_protect (unwind_create_tip_frame, frame); |
12744 |
|
|
12792 |
{ |
{ |
12793 |
tem = Fquery_fontset (font, Qnil); |
tem = Fquery_fontset (font, Qnil); |
12794 |
if (STRINGP (tem)) |
if (STRINGP (tem)) |
12795 |
font = x_new_fontset (f, XSTRING (tem)->data); |
font = x_new_fontset (f, SDATA (tem)); |
12796 |
else |
else |
12797 |
font = x_new_font (f, XSTRING (font)->data); |
font = x_new_font (f, SDATA (font)); |
12798 |
} |
} |
12799 |
|
|
12800 |
/* Try out a font which we hope has bold and italic variations. */ |
/* Try out a font which we hope has bold and italic variations. */ |
12801 |
if (!STRINGP (font)) |
if (!STRINGP (font)) |
12802 |
font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1"); |
font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1"); |
12855 |
f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; |
f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED; |
12856 |
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; |
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window; |
12857 |
|
|
12858 |
window_prompting = x_figure_window_size (f, parms); |
window_prompting = x_figure_window_size (f, parms, 0); |
12859 |
|
|
12860 |
/* No fringes on tip frame. */ |
/* No fringes on tip frame. */ |
12861 |
f->output_data.w32->fringes_extra = 0; |
f->output_data.w32->fringes_extra = 0; |
12863 |
f->output_data.w32->left_fringe_width = 0; |
f->output_data.w32->left_fringe_width = 0; |
12864 |
f->output_data.w32->right_fringe_width = 0; |
f->output_data.w32->right_fringe_width = 0; |
12865 |
|
|
|
if (window_prompting & XNegative) |
|
|
{ |
|
|
if (window_prompting & YNegative) |
|
|
f->output_data.w32->win_gravity = SouthEastGravity; |
|
|
else |
|
|
f->output_data.w32->win_gravity = NorthEastGravity; |
|
|
} |
|
|
else |
|
|
{ |
|
|
if (window_prompting & YNegative) |
|
|
f->output_data.w32->win_gravity = SouthWestGravity; |
|
|
else |
|
|
f->output_data.w32->win_gravity = NorthWestGravity; |
|
|
} |
|
|
|
|
|
f->output_data.w32->size_hint_flags = window_prompting; |
|
|
|
|
12866 |
BLOCK_INPUT; |
BLOCK_INPUT; |
12867 |
my_create_tip_window (f); |
my_create_tip_window (f); |
12868 |
UNBLOCK_INPUT; |
UNBLOCK_INPUT; |
12885 |
SET_FRAME_WIDTH (f, 0); |
SET_FRAME_WIDTH (f, 0); |
12886 |
change_frame_size (f, height, width, 1, 0, 0); |
change_frame_size (f, height, width, 1, 0, 0); |
12887 |
|
|
12888 |
|
/* Add `tooltip' frame parameter's default value. */ |
12889 |
|
if (NILP (Fframe_parameter (frame, intern ("tooltip")))) |
12890 |
|
Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt), |
12891 |
|
Qnil)); |
12892 |
|
|
12893 |
/* Set up faces after all frame parameters are known. This call |
/* Set up faces after all frame parameters are known. This call |
12894 |
also merges in face attributes specified for new frames. |
also merges in face attributes specified for new frames. |
12895 |
|
|
12904 |
/* Set tip_frame here, so that */ |
/* Set tip_frame here, so that */ |
12905 |
tip_frame = frame; |
tip_frame = frame; |
12906 |
call1 (Qface_set_after_frame_default, frame); |
call1 (Qface_set_after_frame_default, frame); |
12907 |
|
|
12908 |
if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) |
if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) |
12909 |
Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), |
Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), |
12910 |
Qnil)); |
Qnil)); |
12911 |
} |
} |
12912 |
|
|
12913 |
f->no_split = 1; |
f->no_split = 1; |
12914 |
|
|
12915 |
UNGCPRO; |
UNGCPRO; |
12949 |
int *root_x, *root_y; |
int *root_x, *root_y; |
12950 |
{ |
{ |
12951 |
Lisp_Object left, top; |
Lisp_Object left, top; |
12952 |
|
|
12953 |
/* User-specified position? */ |
/* User-specified position? */ |
12954 |
left = Fcdr (Fassq (Qleft, parms)); |
left = Fcdr (Fassq (Qleft, parms)); |
12955 |
top = Fcdr (Fassq (Qtop, parms)); |
top = Fcdr (Fassq (Qtop, parms)); |
12956 |
|
|
12957 |
/* Move the tooltip window where the mouse pointer is. Resize and |
/* Move the tooltip window where the mouse pointer is. Resize and |
12958 |
show it. */ |
show it. */ |
12959 |
if (!INTEGERP (left) || !INTEGERP (top)) |
if (!INTEGERP (left) || !INTEGERP (top)) |
13024 |
int i, width, height; |
int i, width, height; |
13025 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
13026 |
int old_windows_or_buffers_changed = windows_or_buffers_changed; |
int old_windows_or_buffers_changed = windows_or_buffers_changed; |
13027 |
int count = BINDING_STACK_SIZE (); |
int count = SPECPDL_INDEX (); |
13028 |
|
|
13029 |
specbind (Qinhibit_redisplay, Qt); |
specbind (Qinhibit_redisplay, Qt); |
13030 |
|
|
13031 |
GCPRO4 (string, parms, frame, timeout); |
GCPRO4 (string, parms, frame, timeout); |
13041 |
dx = make_number (5); |
dx = make_number (5); |
13042 |
else |
else |
13043 |
CHECK_NUMBER (dx); |
CHECK_NUMBER (dx); |
13044 |
|
|
13045 |
if (NILP (dy)) |
if (NILP (dy)) |
13046 |
dy = make_number (-10); |
dy = make_number (-10); |
13047 |
else |
else |
13061 |
&& !NILP (Fequal (last_parms, parms))) |
&& !NILP (Fequal (last_parms, parms))) |
13062 |
{ |
{ |
13063 |
struct frame *f = XFRAME (tip_frame); |
struct frame *f = XFRAME (tip_frame); |
13064 |
|
|
13065 |
/* Only DX and DY have changed. */ |
/* Only DX and DY have changed. */ |
13066 |
if (!NILP (tip_timer)) |
if (!NILP (tip_timer)) |
13067 |
{ |
{ |
13136 |
w->width = make_number (80); |
w->width = make_number (80); |
13137 |
w->height = make_number (40); |
w->height = make_number (40); |
13138 |
} |
} |
13139 |
|
|
13140 |
f->window_width = XINT (w->width); |
f->window_width = XINT (w->width); |
13141 |
adjust_glyphs (f); |
adjust_glyphs (f); |
13142 |
w->pseudo_window_p = 1; |
w->pseudo_window_p = 1; |
13177 |
else |
else |
13178 |
#endif |
#endif |
13179 |
row_width = row->pixel_width; |
row_width = row->pixel_width; |
13180 |
|
|
13181 |
/* TODO: find why tips do not draw along baseline as instructed. */ |
/* TODO: find why tips do not draw along baseline as instructed. */ |
13182 |
height += row->height; |
height += row->height; |
13183 |
width = max (width, row_width); |
width = max (width, row_width); |
13249 |
/* Return quickly if nothing to do. */ |
/* Return quickly if nothing to do. */ |
13250 |
if (NILP (tip_timer) && NILP (tip_frame)) |
if (NILP (tip_timer) && NILP (tip_frame)) |
13251 |
return Qnil; |
return Qnil; |
13252 |
|
|
13253 |
frame = tip_frame; |
frame = tip_frame; |
13254 |
timer = tip_timer; |
timer = tip_timer; |
13255 |
GCPRO2 (frame, timer); |
GCPRO2 (frame, timer); |
13256 |
tip_frame = tip_timer = deleted = Qnil; |
tip_frame = tip_timer = deleted = Qnil; |
13257 |
|
|
13258 |
count = BINDING_STACK_SIZE (); |
count = SPECPDL_INDEX (); |
13259 |
specbind (Qinhibit_redisplay, Qt); |
specbind (Qinhibit_redisplay, Qt); |
13260 |
specbind (Qinhibit_quit, Qt); |
specbind (Qinhibit_quit, Qt); |
13261 |
|
|
13262 |
if (!NILP (timer)) |
if (!NILP (timer)) |
13263 |
call1 (Qcancel_timer, timer); |
call1 (Qcancel_timer, timer); |
13264 |
|
|
13277 |
/*********************************************************************** |
/*********************************************************************** |
13278 |
File selection dialog |
File selection dialog |
13279 |
***********************************************************************/ |
***********************************************************************/ |
|
|
|
13280 |
extern Lisp_Object Qfile_name_history; |
extern Lisp_Object Qfile_name_history; |
13281 |
|
|
13282 |
|
/* Callback for altering the behaviour of the Open File dialog. |
13283 |
|
Makes the Filename text field contain "Current Directory" and be |
13284 |
|
read-only when "Directories" is selected in the filter. This |
13285 |
|
allows us to work around the fact that the standard Open File |
13286 |
|
dialog does not support directories. */ |
13287 |
|
UINT CALLBACK |
13288 |
|
file_dialog_callback (hwnd, msg, wParam, lParam) |
13289 |
|
HWND hwnd; |
13290 |
|
UINT msg; |
13291 |
|
WPARAM wParam; |
13292 |
|
LPARAM lParam; |
13293 |
|
{ |
13294 |
|
if (msg == WM_NOTIFY) |
13295 |
|
{ |
13296 |
|
OFNOTIFY * notify = (OFNOTIFY *)lParam; |
13297 |
|
/* Detect when the Filter dropdown is changed. */ |
13298 |
|
if (notify->hdr.code == CDN_TYPECHANGE) |
13299 |
|
{ |
13300 |
|
HWND dialog = GetParent (hwnd); |
13301 |
|
HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); |
13302 |
|
|
13303 |
|
/* Directories is in index 2. */ |
13304 |
|
if (notify->lpOFN->nFilterIndex == 2) |
13305 |
|
{ |
13306 |
|
CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, |
13307 |
|
"Current Directory"); |
13308 |
|
EnableWindow (edit_control, FALSE); |
13309 |
|
} |
13310 |
|
else |
13311 |
|
{ |
13312 |
|
CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, |
13313 |
|
""); |
13314 |
|
EnableWindow (edit_control, TRUE); |
13315 |
|
} |
13316 |
|
} |
13317 |
|
} |
13318 |
|
return 0; |
13319 |
|
} |
13320 |
|
|
13321 |
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, |
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0, |
13322 |
doc: /* Read file name, prompting with PROMPT in directory DIR. |
doc: /* Read file name, prompting with PROMPT in directory DIR. |
13323 |
Use a file selection dialog. |
Use a file selection dialog. |
13328 |
{ |
{ |
13329 |
struct frame *f = SELECTED_FRAME (); |
struct frame *f = SELECTED_FRAME (); |
13330 |
Lisp_Object file = Qnil; |
Lisp_Object file = Qnil; |
13331 |
int count = specpdl_ptr - specpdl; |
int count = SPECPDL_INDEX (); |
13332 |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
13333 |
char filename[MAX_PATH + 1]; |
char filename[MAX_PATH + 1]; |
13334 |
char init_dir[MAX_PATH + 1]; |
char init_dir[MAX_PATH + 1]; |
|
int use_dialog_p = 1; |
|
13335 |
|
|
13336 |
GCPRO5 (prompt, dir, default_filename, mustmatch, file); |
GCPRO5 (prompt, dir, default_filename, mustmatch, file); |
13337 |
CHECK_STRING (prompt); |
CHECK_STRING (prompt); |
13340 |
/* Create the dialog with PROMPT as title, using DIR as initial |
/* Create the dialog with PROMPT as title, using DIR as initial |
13341 |
directory and using "*" as pattern. */ |
directory and using "*" as pattern. */ |
13342 |
dir = Fexpand_file_name (dir, Qnil); |
dir = Fexpand_file_name (dir, Qnil); |
13343 |
strncpy (init_dir, XSTRING (dir)->data, MAX_PATH); |
strncpy (init_dir, SDATA (dir), MAX_PATH); |
13344 |
init_dir[MAX_PATH] = '\0'; |
init_dir[MAX_PATH] = '\0'; |
13345 |
unixtodos_filename (init_dir); |
unixtodos_filename (init_dir); |
13346 |
|
|
13347 |
if (STRINGP (default_filename)) |
if (STRINGP (default_filename)) |
13348 |
{ |
{ |
13349 |
char *file_name_only; |
char *file_name_only; |
13350 |
char *full_path_name = XSTRING (default_filename)->data; |
char *full_path_name = SDATA (default_filename); |
13351 |
|
|
13352 |
unixtodos_filename (full_path_name); |
unixtodos_filename (full_path_name); |
13353 |
|
|
13357 |
else |
else |
13358 |
{ |
{ |
13359 |
file_name_only++; |
file_name_only++; |
|
|
|
|
/* If default_file_name is a directory, don't use the open |
|
|
file dialog, as it does not support selecting |
|
|
directories. */ |
|
|
if (!(*file_name_only)) |
|
|
use_dialog_p = 0; |
|
13360 |
} |
} |
13361 |
|
|
13362 |
strncpy (filename, file_name_only, MAX_PATH); |
strncpy (filename, file_name_only, MAX_PATH); |
13365 |
else |
else |
13366 |
filename[0] = '\0'; |
filename[0] = '\0'; |
13367 |
|
|
13368 |
if (use_dialog_p) |
{ |
13369 |
{ |
OPENFILENAME file_details; |
|
OPENFILENAME file_details; |
|
13370 |
|
|
13371 |
/* Prevent redisplay. */ |
/* Prevent redisplay. */ |
13372 |
specbind (Qinhibit_redisplay, Qt); |
specbind (Qinhibit_redisplay, Qt); |
13373 |
BLOCK_INPUT; |
BLOCK_INPUT; |
13374 |
|
|
13375 |
bzero (&file_details, sizeof (file_details)); |
bzero (&file_details, sizeof (file_details)); |
13376 |
file_details.lStructSize = sizeof (file_details); |
file_details.lStructSize = sizeof (file_details); |
13377 |
file_details.hwndOwner = FRAME_W32_WINDOW (f); |
file_details.hwndOwner = FRAME_W32_WINDOW (f); |
13378 |
/* Undocumented Bug in Common File Dialog: |
/* Undocumented Bug in Common File Dialog: |
13379 |
If a filter is not specified, shell links are not resolved. */ |
If a filter is not specified, shell links are not resolved. */ |
13380 |
file_details.lpstrFilter = "ALL Files (*.*)\0*.*\0\0"; |
file_details.lpstrFilter = "All Files (*.*)\0*.*\0Directories\0*|*\0\0"; |
13381 |
file_details.lpstrFile = filename; |
file_details.lpstrFile = filename; |
13382 |
file_details.nMaxFile = sizeof (filename); |
file_details.nMaxFile = sizeof (filename); |
13383 |
file_details.lpstrInitialDir = init_dir; |
file_details.lpstrInitialDir = init_dir; |
13384 |
file_details.lpstrTitle = XSTRING (prompt)->data; |
file_details.lpstrTitle = SDATA (prompt); |
13385 |
file_details.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR; |
file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
13386 |
|
| OFN_EXPLORER | OFN_ENABLEHOOK); |
13387 |
|
if (!NILP (mustmatch)) |
13388 |
|
file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; |
13389 |
|
|
13390 |
if (!NILP (mustmatch)) |
file_details.lpfnHook = (LPOFNHOOKPROC) file_dialog_callback; |
|
file_details.Flags |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; |
|
13391 |
|
|
13392 |
if (GetOpenFileName (&file_details)) |
if (GetOpenFileName (&file_details)) |
13393 |
{ |
{ |
13394 |
dostounix_filename (filename); |
dostounix_filename (filename); |
13395 |
file = DECODE_FILE(build_string (filename)); |
if (file_details.nFilterIndex == 2) |
13396 |
} |
{ |
13397 |
else |
/* "Folder Only" selected - strip dummy file name. */ |
13398 |
file = Qnil; |
char * last = strrchr (filename, '/'); |
13399 |
|
*last = '\0'; |
13400 |
|
} |
13401 |
|
|
13402 |
UNBLOCK_INPUT; |
file = DECODE_FILE(build_string (filename)); |
13403 |
file = unbind_to (count, file); |
} |
13404 |
} |
/* User cancelled the dialog without making a selection. */ |
13405 |
/* Open File dialog will not allow folders to be selected, so resort |
else if (!CommDlgExtendedError ()) |
13406 |
to minibuffer completing reads for directories. */ |
file = Qnil; |
13407 |
else |
/* An error occurred, fallback on reading from the mini-buffer. */ |
13408 |
file = Fcompleting_read (prompt, intern ("read-file-name-internal"), |
else |
13409 |
dir, mustmatch, dir, Qfile_name_history, |
file = Fcompleting_read (prompt, intern ("read-file-name-internal"), |
13410 |
default_filename, Qnil); |
dir, mustmatch, dir, Qfile_name_history, |
13411 |
|
default_filename, Qnil); |
13412 |
|
|
13413 |
|
UNBLOCK_INPUT; |
13414 |
|
file = unbind_to (count, file); |
13415 |
|
} |
13416 |
|
|
13417 |
UNGCPRO; |
UNGCPRO; |
13418 |
|
|
13534 |
document = ENCODE_FILE (document); |
document = ENCODE_FILE (document); |
13535 |
if ((int) ShellExecute (NULL, |
if ((int) ShellExecute (NULL, |
13536 |
(STRINGP (operation) ? |
(STRINGP (operation) ? |
13537 |
XSTRING (operation)->data : NULL), |
SDATA (operation) : NULL), |
13538 |
XSTRING (document)->data, |
SDATA (document), |
13539 |
(STRINGP (parameters) ? |
(STRINGP (parameters) ? |
13540 |
XSTRING (parameters)->data : NULL), |
SDATA (parameters) : NULL), |
13541 |
XSTRING (current_dir)->data, |
SDATA (current_dir), |
13542 |
(INTEGERP (show_flag) ? |
(INTEGERP (show_flag) ? |
13543 |
XINT (show_flag) : SW_SHOWDEFAULT)) |
XINT (show_flag) : SW_SHOWDEFAULT)) |
13544 |
> 32) |
> 32) |
13600 |
c = Fcar (c); |
c = Fcar (c); |
13601 |
if (!SYMBOLP (c)) |
if (!SYMBOLP (c)) |
13602 |
abort (); |
abort (); |
13603 |
vk_code = lookup_vk_code (XSTRING (SYMBOL_NAME (c))->data); |
vk_code = lookup_vk_code (SDATA (SYMBOL_NAME (c))); |
13604 |
} |
} |
13605 |
else if (INTEGERP (c)) |
else if (INTEGERP (c)) |
13606 |
{ |
{ |
13804 |
/* On Windows, we may need to specify the root directory of the |
/* On Windows, we may need to specify the root directory of the |
13805 |
volume holding FILENAME. */ |
volume holding FILENAME. */ |
13806 |
char rootname[MAX_PATH]; |
char rootname[MAX_PATH]; |
13807 |
char *name = XSTRING (encoded)->data; |
char *name = SDATA (encoded); |
13808 |
|
|
13809 |
/* find the root name of the volume if given */ |
/* find the root name of the volume if given */ |
13810 |
if (isalpha (name[0]) && name[1] == ':') |
if (isalpha (name[0]) && name[1] == ':') |
13874 |
Initialization |
Initialization |
13875 |
***********************************************************************/ |
***********************************************************************/ |
13876 |
|
|
13877 |
|
/* Keep this list in the same order as frame_parms in frame.c. |
13878 |
|
Use 0 for unsupported frame parameters. */ |
13879 |
|
|
13880 |
|
frame_parm_handler w32_frame_parm_handlers[] = |
13881 |
|
{ |
13882 |
|
x_set_autoraise, |
13883 |
|
x_set_autolower, |
13884 |
|
x_set_background_color, |
13885 |
|
x_set_border_color, |
13886 |
|
x_set_border_width, |
13887 |
|
x_set_cursor_color, |
13888 |
|
x_set_cursor_type, |
13889 |
|
x_set_font, |
13890 |
|
x_set_foreground_color, |
13891 |
|
x_set_icon_name, |
13892 |
|
x_set_icon_type, |
13893 |
|
x_set_internal_border_width, |
13894 |
|
x_set_menu_bar_lines, |
13895 |
|
x_set_mouse_color, |
13896 |
|
x_explicitly_set_name, |
13897 |
|
x_set_scroll_bar_width, |
13898 |
|
x_set_title, |
13899 |
|
x_set_unsplittable, |
13900 |
|
x_set_vertical_scroll_bars, |
13901 |
|
x_set_visibility, |
13902 |
|
x_set_tool_bar_lines, |
13903 |
|
0, /* x_set_scroll_bar_foreground, */ |
13904 |
|
0, /* x_set_scroll_bar_background, */ |
13905 |
|
x_set_screen_gamma, |
13906 |
|
x_set_line_spacing, |
13907 |
|
x_set_fringe_width, |
13908 |
|
x_set_fringe_width, |
13909 |
|
0, /* x_set_wait_for_wm, */ |
13910 |
|
x_set_fullscreen, |
13911 |
|
}; |
13912 |
|
|
13913 |
void |
void |
13914 |
syms_of_w32fns () |
syms_of_w32fns () |
13915 |
{ |
{ |
13916 |
HMODULE user32_lib = GetModuleHandle ("user32.dll"); |
globals_of_w32fns (); |
|
|
|
13917 |
/* This is zero if not using MS-Windows. */ |
/* This is zero if not using MS-Windows. */ |
13918 |
w32_in_use = 0; |
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 = GetProcAddress (user32_lib, "TrackMouseEvent"); |
|
13919 |
track_mouse_window = NULL; |
track_mouse_window = NULL; |
13920 |
|
|
13921 |
w32_visible_system_caret_hwnd = NULL; |
w32_visible_system_caret_hwnd = NULL; |
13922 |
|
|
|
Qauto_raise = intern ("auto-raise"); |
|
|
staticpro (&Qauto_raise); |
|
|
Qauto_lower = intern ("auto-lower"); |
|
|
staticpro (&Qauto_lower); |
|
|
Qbar = intern ("bar"); |
|
|
staticpro (&Qbar); |
|
|
Qhbar = intern ("hbar"); |
|
|
staticpro (&Qhbar); |
|
|
Qborder_color = intern ("border-color"); |
|
|
staticpro (&Qborder_color); |
|
|
Qborder_width = intern ("border-width"); |
|
|
staticpro (&Qborder_width); |
|
|
Qbox = intern ("box"); |
|
|
staticpro (&Qbox); |
|
|
Qcursor_color = intern ("cursor-color"); |
|
|
staticpro (&Qcursor_color); |
|
|
Qcursor_type = intern ("cursor-type"); |
|
|
staticpro (&Qcursor_type); |
|
|
Qgeometry = intern ("geometry"); |
|
|
staticpro (&Qgeometry); |
|
|
Qicon_left = intern ("icon-left"); |
|
|
staticpro (&Qicon_left); |
|
|
Qicon_top = intern ("icon-top"); |
|
|
staticpro (&Qicon_top); |
|
|
Qicon_type = intern ("icon-type"); |
|
|
staticpro (&Qicon_type); |
|
|
Qicon_name = intern ("icon-name"); |
|
|
staticpro (&Qicon_name); |
|
|
Qinternal_border_width = intern ("internal-border-width"); |
|
|
staticpro (&Qinternal_border_width); |
|
|
Qleft = intern ("left"); |
|
|
staticpro (&Qleft); |
|
|
Qright = intern ("right"); |
|
|
staticpro (&Qright); |
|
|
Qmouse_color = intern ("mouse-color"); |
|
|
staticpro (&Qmouse_color); |
|
13923 |
Qnone = intern ("none"); |
Qnone = intern ("none"); |
13924 |
staticpro (&Qnone); |
staticpro (&Qnone); |
|
Qparent_id = intern ("parent-id"); |
|
|
staticpro (&Qparent_id); |
|
|
Qscroll_bar_width = intern ("scroll-bar-width"); |
|
|
staticpro (&Qscroll_bar_width); |
|
13925 |
Qsuppress_icon = intern ("suppress-icon"); |
Qsuppress_icon = intern ("suppress-icon"); |
13926 |
staticpro (&Qsuppress_icon); |
staticpro (&Qsuppress_icon); |
13927 |
Qundefined_color = intern ("undefined-color"); |
Qundefined_color = intern ("undefined-color"); |
13928 |
staticpro (&Qundefined_color); |
staticpro (&Qundefined_color); |
|
Qvertical_scroll_bars = intern ("vertical-scroll-bars"); |
|
|
staticpro (&Qvertical_scroll_bars); |
|
|
Qvisibility = intern ("visibility"); |
|
|
staticpro (&Qvisibility); |
|
|
Qwindow_id = intern ("window-id"); |
|
|
staticpro (&Qwindow_id); |
|
|
Qx_frame_parameter = intern ("x-frame-parameter"); |
|
|
staticpro (&Qx_frame_parameter); |
|
|
Qx_resource_name = intern ("x-resource-name"); |
|
|
staticpro (&Qx_resource_name); |
|
|
Quser_position = intern ("user-position"); |
|
|
staticpro (&Quser_position); |
|
|
Quser_size = intern ("user-size"); |
|
|
staticpro (&Quser_size); |
|
|
Qscreen_gamma = intern ("screen-gamma"); |
|
|
staticpro (&Qscreen_gamma); |
|
|
Qline_spacing = intern ("line-spacing"); |
|
|
staticpro (&Qline_spacing); |
|
13929 |
Qcenter = intern ("center"); |
Qcenter = intern ("center"); |
13930 |
staticpro (&Qcenter); |
staticpro (&Qcenter); |
13931 |
Qcancel_timer = intern ("cancel-timer"); |
Qcancel_timer = intern ("cancel-timer"); |
13932 |
staticpro (&Qcancel_timer); |
staticpro (&Qcancel_timer); |
|
Qfullscreen = intern ("fullscreen"); |
|
|
staticpro (&Qfullscreen); |
|
|
Qfullwidth = intern ("fullwidth"); |
|
|
staticpro (&Qfullwidth); |
|
|
Qfullheight = intern ("fullheight"); |
|
|
staticpro (&Qfullheight); |
|
|
Qfullboth = intern ("fullboth"); |
|
|
staticpro (&Qfullboth); |
|
13933 |
|
|
13934 |
Qhyper = intern ("hyper"); |
Qhyper = intern ("hyper"); |
13935 |
staticpro (&Qhyper); |
staticpro (&Qhyper); |
13967 |
QCmask = intern (":mask"); |
QCmask = intern (":mask"); |
13968 |
staticpro (&QCmask); |
staticpro (&QCmask); |
13969 |
|
|
|
Qface_set_after_frame_default = intern ("face-set-after-frame-default"); |
|
|
staticpro (&Qface_set_after_frame_default); |
|
|
|
|
13970 |
Fput (Qundefined_color, Qerror_conditions, |
Fput (Qundefined_color, Qerror_conditions, |
13971 |
Fcons (Qundefined_color, Fcons (Qerror, Qnil))); |
Fcons (Qundefined_color, Fcons (Qerror, Qnil))); |
13972 |
Fput (Qundefined_color, Qerror_message, |
Fput (Qundefined_color, Qerror_message, |
13994 |
doc: /* If non-zero, the virtual key code for an alternative quit key. */); |
doc: /* If non-zero, the virtual key code for an alternative quit key. */); |
13995 |
XSETINT (Vw32_quit_key, 0); |
XSETINT (Vw32_quit_key, 0); |
13996 |
|
|
13997 |
DEFVAR_LISP ("w32-pass-lwindow-to-system", |
DEFVAR_LISP ("w32-pass-lwindow-to-system", |
13998 |
&Vw32_pass_lwindow_to_system, |
&Vw32_pass_lwindow_to_system, |
13999 |
doc: /* Non-nil if the left \"Windows\" key is passed on to Windows. |
doc: /* Non-nil if the left \"Windows\" key is passed on to Windows. |
14000 |
When non-nil, the Start menu is opened by tapping the key. */); |
When non-nil, the Start menu is opened by tapping the key. */); |
14001 |
Vw32_pass_lwindow_to_system = Qt; |
Vw32_pass_lwindow_to_system = Qt; |
14002 |
|
|
14003 |
DEFVAR_LISP ("w32-pass-rwindow-to-system", |
DEFVAR_LISP ("w32-pass-rwindow-to-system", |
14004 |
&Vw32_pass_rwindow_to_system, |
&Vw32_pass_rwindow_to_system, |
14005 |
doc: /* Non-nil if the right \"Windows\" key is passed on to Windows. |
doc: /* Non-nil if the right \"Windows\" key is passed on to Windows. |
14006 |
When non-nil, the Start menu is opened by tapping the key. */); |
When non-nil, the Start menu is opened by tapping the key. */); |
14018 |
means that this hack won't interfere with any real key code. */ |
means that this hack won't interfere with any real key code. */ |
14019 |
Vw32_phantom_key_code = 255; |
Vw32_phantom_key_code = 255; |
14020 |
|
|
14021 |
DEFVAR_LISP ("w32-enable-num-lock", |
DEFVAR_LISP ("w32-enable-num-lock", |
14022 |
&Vw32_enable_num_lock, |
&Vw32_enable_num_lock, |
14023 |
doc: /* Non-nil if Num Lock should act normally. |
doc: /* Non-nil if Num Lock should act normally. |
14024 |
Set to nil to see Num Lock as the key `kp-numlock'. */); |
Set to nil to see Num Lock as the key `kp-numlock'. */); |
14025 |
Vw32_enable_num_lock = Qt; |
Vw32_enable_num_lock = Qt; |
14026 |
|
|
14027 |
DEFVAR_LISP ("w32-enable-caps-lock", |
DEFVAR_LISP ("w32-enable-caps-lock", |
14028 |
&Vw32_enable_caps_lock, |
&Vw32_enable_caps_lock, |
14029 |
doc: /* Non-nil if Caps Lock should act normally. |
doc: /* Non-nil if Caps Lock should act normally. |
14030 |
Set to nil to see Caps Lock as the key `capslock'. */); |
Set to nil to see Caps Lock as the key `capslock'. */); |
14097 |
system to handle them. */); |
system to handle them. */); |
14098 |
w32_pass_extra_mouse_buttons_to_system = 0; |
w32_pass_extra_mouse_buttons_to_system = 0; |
14099 |
|
|
|
init_x_parm_symbols (); |
|
|
|
|
14100 |
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, |
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path, |
14101 |
doc: /* List of directories to search for bitmap files for w32. */); |
doc: /* List of directories to search for window system bitmap files. */); |
14102 |
Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH"); |
Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH"); |
14103 |
|
|
14104 |
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, |
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape, |
14107 |
unless you set the mouse color. */); |
unless you set the mouse color. */); |
14108 |
Vx_pointer_shape = Qnil; |
Vx_pointer_shape = Qnil; |
14109 |
|
|
|
DEFVAR_LISP ("x-resource-name", &Vx_resource_name, |
|
|
doc: /* The name Emacs uses to look up resources; for internal use only. |
|
|
`x-get-resource' uses this as the first component of the instance name |
|
|
when requesting resource values. |
|
|
Emacs initially sets `x-resource-name' to the name under which Emacs |
|
|
was invoked, or to the value specified with the `-name' or `-rn' |
|
|
switches, if present. */); |
|
|
Vx_resource_name = Qnil; |
|
|
|
|
14110 |
Vx_nontext_pointer_shape = Qnil; |
Vx_nontext_pointer_shape = Qnil; |
14111 |
|
|
14112 |
Vx_mode_pointer_shape = Qnil; |
Vx_mode_pointer_shape = Qnil; |
14120 |
DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, |
DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, |
14121 |
doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); |
doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); |
14122 |
display_hourglass_p = 1; |
display_hourglass_p = 1; |
14123 |
|
|
14124 |
DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, |
DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, |
14125 |
doc: /* *Seconds to wait before displaying an hourglass pointer. |
doc: /* *Seconds to wait before displaying an hourglass pointer. |
14126 |
Value must be an integer or float. */); |
Value must be an integer or float. */); |
14148 |
doc: /* Maximum size for tooltips. |
doc: /* Maximum size for tooltips. |
14149 |
Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); |
Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */); |
14150 |
Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); |
Vx_max_tooltip_size = Fcons (make_number (80), make_number (40)); |
14151 |
|
|
14152 |
DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, |
DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager, |
14153 |
doc: /* Non-nil if no window manager is in use. |
doc: /* Non-nil if no window manager is in use. |
14154 |
Emacs doesn't try to figure this out; this is always nil |
Emacs doesn't try to figure this out; this is always nil |
14281 |
Qw32_charset_unicode = intern ("w32-charset-unicode"); |
Qw32_charset_unicode = intern ("w32-charset-unicode"); |
14282 |
#endif |
#endif |
14283 |
|
|
|
defsubr (&Sx_get_resource); |
|
14284 |
#if 0 /* TODO: Port to W32 */ |
#if 0 /* TODO: Port to W32 */ |
14285 |
defsubr (&Sx_change_window_property); |
defsubr (&Sx_change_window_property); |
14286 |
defsubr (&Sx_delete_window_property); |
defsubr (&Sx_delete_window_property); |
14303 |
defsubr (&Sx_display_visual_class); |
defsubr (&Sx_display_visual_class); |
14304 |
defsubr (&Sx_display_backing_store); |
defsubr (&Sx_display_backing_store); |
14305 |
defsubr (&Sx_display_save_under); |
defsubr (&Sx_display_save_under); |
|
defsubr (&Sx_parse_geometry); |
|
14306 |
defsubr (&Sx_create_frame); |
defsubr (&Sx_create_frame); |
14307 |
defsubr (&Sx_open_connection); |
defsubr (&Sx_open_connection); |
14308 |
defsubr (&Sx_close_connection); |
defsubr (&Sx_close_connection); |
14358 |
staticpro (&QCrelief); |
staticpro (&QCrelief); |
14359 |
Qpostscript = intern ("postscript"); |
Qpostscript = intern ("postscript"); |
14360 |
staticpro (&Qpostscript); |
staticpro (&Qpostscript); |
|
#if 0 /* TODO: These need entries at top of file. */ |
|
14361 |
QCloader = intern (":loader"); |
QCloader = intern (":loader"); |
14362 |
staticpro (&QCloader); |
staticpro (&QCloader); |
14363 |
QCbounding_box = intern (":bounding-box"); |
QCbounding_box = intern (":bounding-box"); |
14366 |
staticpro (&QCpt_width); |
staticpro (&QCpt_width); |
14367 |
QCpt_height = intern (":pt-height"); |
QCpt_height = intern (":pt-height"); |
14368 |
staticpro (&QCpt_height); |
staticpro (&QCpt_height); |
|
#endif |
|
14369 |
QCindex = intern (":index"); |
QCindex = intern (":index"); |
14370 |
staticpro (&QCindex); |
staticpro (&QCindex); |
14371 |
Qpbm = intern ("pbm"); |
Qpbm = intern ("pbm"); |
14375 |
Qxpm = intern ("xpm"); |
Qxpm = intern ("xpm"); |
14376 |
staticpro (&Qxpm); |
staticpro (&Qxpm); |
14377 |
#endif |
#endif |
14378 |
|
|
14379 |
#if HAVE_JPEG |
#if HAVE_JPEG |
14380 |
Qjpeg = intern ("jpeg"); |
Qjpeg = intern ("jpeg"); |
14381 |
staticpro (&Qjpeg); |
staticpro (&Qjpeg); |
14382 |
#endif |
#endif |
14383 |
|
|
14384 |
#if HAVE_TIFF |
#if HAVE_TIFF |
14385 |
Qtiff = intern ("tiff"); |
Qtiff = intern ("tiff"); |
14386 |
staticpro (&Qtiff); |
staticpro (&Qtiff); |
14387 |
#endif |
#endif |
14388 |
|
|
14389 |
#if HAVE_GIF |
#if HAVE_GIF |
14390 |
Qgif = intern ("gif"); |
Qgif = intern ("gif"); |
14421 |
} |
} |
14422 |
|
|
14423 |
|
|
14424 |
void |
/* |
14425 |
init_xfns () |
globals_of_w32fns is used to initialize those global variables that |
14426 |
|
must always be initialized on startup even when the global variable |
14427 |
|
initialized is non zero (see the function main in emacs.c). |
14428 |
|
globals_of_w32fns is called from syms_of_w32fns when the global |
14429 |
|
variable initialized is 0 and directly from main when initialized |
14430 |
|
is non zero. |
14431 |
|
*/ |
14432 |
|
void globals_of_w32fns () |
14433 |
{ |
{ |
14434 |
image_types = NULL; |
HMODULE user32_lib = GetModuleHandle ("user32.dll"); |
14435 |
Vimage_types = Qnil; |
/* |
14436 |
|
TrackMouseEvent not available in all versions of Windows, so must load |
14437 |
|
it dynamically. Do it once, here, instead of every time it is used. |
14438 |
|
*/ |
14439 |
|
track_mouse_event_fn = (TrackMouseEvent_Proc) GetProcAddress (user32_lib, "TrackMouseEvent"); |
14440 |
|
} |
14441 |
|
|
14442 |
|
/* Initialize image types. Based on which libraries are available. */ |
14443 |
|
static void |
14444 |
|
init_external_image_libraries () |
14445 |
|
{ |
14446 |
|
HINSTANCE library; |
14447 |
|
|
|
define_image_type (&pbm_type); |
|
|
define_image_type (&xbm_type); |
|
|
#if 0 /* TODO : Image support for W32 */ |
|
|
define_image_type (&gs_type); |
|
|
#endif |
|
|
|
|
14448 |
#if HAVE_XPM |
#if HAVE_XPM |
14449 |
define_image_type (&xpm_type); |
if ((library = LoadLibrary ("libXpm.dll"))) |
14450 |
|
{ |
14451 |
|
if (init_xpm_functions (library)) |
14452 |
|
define_image_type (&xpm_type); |
14453 |
|
} |
14454 |
|
|
14455 |
#endif |
#endif |
14456 |
|
|
14457 |
#if HAVE_JPEG |
#if HAVE_JPEG |
14458 |
define_image_type (&jpeg_type); |
/* Try loading jpeg library under probable names. */ |
14459 |
|
if ((library = LoadLibrary ("libjpeg.dll")) |
14460 |
|
|| (library = LoadLibrary ("jpeg-62.dll")) |
14461 |
|
|| (library = LoadLibrary ("jpeg.dll"))) |
14462 |
|
{ |
14463 |
|
if (init_jpeg_functions (library)) |
14464 |
|
define_image_type (&jpeg_type); |
14465 |
|
} |
14466 |
#endif |
#endif |
14467 |
|
|
14468 |
#if HAVE_TIFF |
#if HAVE_TIFF |
14469 |
define_image_type (&tiff_type); |
if (library = LoadLibrary ("libtiff.dll")) |
14470 |
|
{ |
14471 |
|
if (init_tiff_functions (library)) |
14472 |
|
define_image_type (&tiff_type); |
14473 |
|
} |
14474 |
#endif |
#endif |
14475 |
|
|
14476 |
#if HAVE_GIF |
#if HAVE_GIF |
14477 |
define_image_type (&gif_type); |
if (library = LoadLibrary ("libungif.dll")) |
14478 |
|
{ |
14479 |
|
if (init_gif_functions (library)) |
14480 |
|
define_image_type (&gif_type); |
14481 |
|
} |
14482 |
#endif |
#endif |
14483 |
|
|
14484 |
#if HAVE_PNG |
#if HAVE_PNG |
14485 |
define_image_type (&png_type); |
/* Ensure zlib is loaded. Try debug version first. */ |
14486 |
|
if (!LoadLibrary ("zlibd.dll")) |
14487 |
|
LoadLibrary ("zlib.dll"); |
14488 |
|
|
14489 |
|
/* Try loading libpng under probable names. */ |
14490 |
|
if ((library = LoadLibrary ("libpng13d.dll")) |
14491 |
|
|| (library = LoadLibrary ("libpng13.dll")) |
14492 |
|
|| (library = LoadLibrary ("libpng12d.dll")) |
14493 |
|
|| (library = LoadLibrary ("libpng12.dll")) |
14494 |
|
|| (library = LoadLibrary ("libpng.dll"))) |
14495 |
|
{ |
14496 |
|
if (init_png_functions (library)) |
14497 |
|
define_image_type (&png_type); |
14498 |
|
} |
14499 |
#endif |
#endif |
14500 |
} |
} |
14501 |
|
|
14502 |
|
void |
14503 |
|
init_xfns () |
14504 |
|
{ |
14505 |
|
image_types = NULL; |
14506 |
|
Vimage_types = Qnil; |
14507 |
|
|
14508 |
|
define_image_type (&pbm_type); |
14509 |
|
define_image_type (&xbm_type); |
14510 |
|
|
14511 |
|
#if 0 /* TODO : Ghostscript support for W32 */ |
14512 |
|
define_image_type (&gs_type); |
14513 |
|
#endif |
14514 |
|
|
14515 |
|
/* Image types that rely on external libraries are loaded dynamically |
14516 |
|
if the library is available. */ |
14517 |
|
init_external_image_libraries (); |
14518 |
|
} |
14519 |
|
|
14520 |
#undef abort |
#undef abort |
14521 |
|
|
14522 |
void |
void |
14523 |
w32_abort() |
w32_abort() |
14524 |
{ |
{ |
14525 |
int button; |
int button; |