#include <shellapi.h>
#include <ctype.h>
-#define max(a, b) ((a) > (b) ? (a) : (b))
-
extern void free_frame_menubar ();
+extern void x_compute_fringe_widths P_ ((struct frame *, int));
extern double atof ();
-extern int w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state);
+extern int w32_console_toggle_lock_key P_ ((int, Lisp_Object));
+extern void w32_menu_display_help P_ ((HWND, HMENU, UINT, UINT));
+extern void w32_free_menu_strings P_ ((HWND));
+
extern int quit_char;
/* A definition of XColor for non-X frames. */
/* Switch to control whether we inhibit requests for synthesized bold
and italic versions of fonts. */
-Lisp_Object Vw32_enable_synthesized_fonts;
+int w32_enable_synthesized_fonts;
/* Enable palette management. */
Lisp_Object Vw32_enable_palette;
events that are passed on to the event loop. */
Lisp_Object Vw32_mouse_move_interval;
+/* Flag to indicate if XBUTTON events should be passed on to Windows. */
+int w32_pass_extra_mouse_buttons_to_system;
+
/* The name we're using in resource queries. */
Lisp_Object Vx_resource_name;
/* Alist of bdf fonts and the files that define them. */
Lisp_Object Vw32_bdf_filename_alist;
-Lisp_Object Vw32_system_coding_system;
-
/* A flag to control whether fonts are matched strictly or not. */
int w32_strict_fontnames;
Lisp_Object Qw32_charset_unicode;
#endif
+Lisp_Object Qfullscreen;
+Lisp_Object Qfullwidth;
+Lisp_Object Qfullheight;
+Lisp_Object Qfullboth;
+
extern Lisp_Object Qtop;
extern Lisp_Object Qdisplay;
-extern Lisp_Object Qtool_bar_lines;
/* State variables for emulating a three button mouse. */
#define LMOUSE 1
static int button_state = 0;
static W32Msg saved_mouse_button_msg;
-static unsigned mouse_button_timer; /* non-zero when timer is active */
+static unsigned mouse_button_timer = 0; /* non-zero when timer is active */
static W32Msg saved_mouse_move_msg;
-static unsigned mouse_move_timer;
+static unsigned mouse_move_timer = 0;
+
+/* Window that is tracking the mouse. */
+static HWND track_mouse_window;
+FARPROC track_mouse_event_fn;
/* W95 mousewheel handler */
unsigned int msh_mousewheel = 0;
+/* Timers */
#define MOUSE_BUTTON_ID 1
#define MOUSE_MOVE_ID 2
+#define MENU_FREE_ID 3
+/* The delay (milliseconds) before a menu is freed after WM_EXITMENULOOP
+ is received. */
+#define MENU_FREE_DELAY 1000
+static unsigned menu_free_timer = 0;
/* The below are defined in frame.c. */
extern Lisp_Object Vw32_recognize_altgr;
extern HWND w32_system_caret_hwnd;
-extern int w32_system_caret_width;
+
extern int w32_system_caret_height;
extern int w32_system_caret_x;
extern int w32_system_caret_y;
+extern int w32_use_visible_system_caret;
+
+static HWND w32_visible_system_caret_hwnd;
\f
/* Error if we are not connected to MS-Windows. */
if (f->output_data.w32->hourglass_window == wdesc)
return f;
- /* TODO: Check tooltips when supported. */
if (FRAME_W32_WINDOW (f) == wdesc)
return f;
}
}
/* Search bitmap-file-path for the file, if appropriate. */
- fd = openp (Vx_bitmap_file_path, file, Qnil, &found, 0);
+ fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
if (fd < 0)
return -1;
emacs_close (fd);
void (*setter) P_ ((struct frame *, Lisp_Object, Lisp_Object));
};
+BOOL my_show_window P_ ((struct frame *, HWND, int));
+void my_set_window_pos P_ ((HWND, HWND, int, int, int, int, UINT));
static Lisp_Object unwind_create_frame P_ ((Lisp_Object));
static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object));
static void x_change_window_heights P_ ((Lisp_Object, int));
/* TODO: Native Input Method support; see x_create_im. */
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));
void x_set_background_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_mouse_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_cursor_color P_ ((struct frame *, Lisp_Object, Lisp_Object));
void x_set_icon_type 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));
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
+ {"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
make_number (i));
}
\f
+/* 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. */
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;
/* 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))
+ if (EQ (prop, Qforeground_color)
+ || EQ (prop, Qbackground_color)
+ || EQ (prop, Qfont)
+ || EQ (prop, Qfullscreen))
{
register Lisp_Object param_index, old_value;
- param_index = Fget (prop, Qx_frame_parameter);
old_value = get_frame_param (f, prop);
- store_frame_param (f, prop, val);
- 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);
+ 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);
+ }
}
}
icon_top = val;
else if (EQ (prop, Qicon_left))
icon_left = val;
- else if (EQ (prop, Qforeground_color) || EQ (prop, Qbackground_color))
+ 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;
- param_index = Fget (prop, Qx_frame_parameter);
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])))
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
int *xptr, *yptr;
{
POINT pt;
+ RECT rect;
- {
- RECT rect;
-
- GetClientRect(FRAME_W32_WINDOW(f), &rect);
- AdjustWindowRect(&rect, f->output_data.w32->dwStyle, FRAME_EXTERNAL_MENU_BAR(f));
-
- pt.x = rect.left;
- pt.y = rect.top;
- }
+ GetClientRect(FRAME_W32_WINDOW(f), &rect);
+ AdjustWindowRect(&rect, f->output_data.w32->dwStyle, FRAME_EXTERNAL_MENU_BAR(f));
+
+ pt.x = rect.left;
+ pt.y = rect.top;
ClientToScreen (FRAME_W32_WINDOW(f), &pt);
+ /* Remember x_pixels_diff and y_pixels_diff. */
+ f->output_data.w32->x_pixels_diff = pt.x - rect.left;
+ f->output_data.w32->y_pixels_diff = pt.y - rect.top;
+
*xptr = pt.x;
*yptr = pt.y;
}
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));
}
\f
-DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color, Sw32_define_rgb_color, 4, 4, 0,
- "Convert RGB numbers to a windows color reference and associate with NAME (a string).\n\
-This adds or updates a named color to w32-color-map, making it available for use.\n\
-The original entry's RGB ref is returned, or nil if the entry is new.")
+DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
+ Sw32_define_rgb_color, 4, 4, 0,
+ doc: /* Convert RGB numbers to a windows color reference and associate with NAME.
+This adds or updates a named color to w32-color-map, making it
+available for use. The original entry's RGB ref is returned, or nil
+if the entry is new. */)
(red, green, blue, name)
Lisp_Object red, green, blue, name;
{
return (oldrgb);
}
-DEFUN ("w32-load-color-file", Fw32_load_color_file, Sw32_load_color_file, 1, 1, 0,
- "Create an alist of color entries from an external file (ie. rgb.txt).\n\
-Assign this value to w32-color-map to replace the existing color map.\n\
-\
-The file should define one named RGB color per line like so:\
- R G B name\n\
-where R,G,B are numbers between 0 and 255 and name is an arbitrary string.")
+DEFUN ("w32-load-color-file", Fw32_load_color_file,
+ Sw32_load_color_file, 1, 1, 0,
+ doc: /* Create an alist of color entries from an external file.
+Assign this value to w32-color-map to replace the existing color map.
+
+The file should define one named RGB color per line like so:
+ R G B name
+where R,G,B are numbers between 0 and 255 and name is an arbitrary string. */)
(filename)
Lisp_Object filename;
{
};
DEFUN ("w32-default-color-map", Fw32_default_color_map, Sw32_default_color_map,
- 0, 0, 0, "Return the default color map.")
+ 0, 0, 0, doc: /* Return the default color map. */)
()
{
int i;
}
+/* 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. */
fore_pixel = FRAME_BACKGROUND_PIXEL (f);
}
- FRAME_FOREGROUND_PIXEL (f) = fore_pixel;
+ f->output_data.w32->cursor_foreground_pixel = fore_pixel;
f->output_data.w32->cursor_pixel = pixel;
if (FRAME_W32_WINDOW (f) != 0)
{
+ BLOCK_INPUT;
+ /* Update frame's cursor_gc. */
+ f->output_data.w32->cursor_gc->foreground = fore_pixel;
+ f->output_data.w32->cursor_gc->background = pixel;
+
+ UNBLOCK_INPUT;
+
if (FRAME_VISIBLE_P (f))
{
x_update_cursor (f, 0);
}
}
+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;
SET_FRAME_GARBAGED (f);
do_pending_window_change (0);
}
+ else
+ SET_FRAME_GARBAGED (f);
}
void
extern char *x_get_string_resource ();
DEFUN ("x-get-resource", Fx_get_resource, Sx_get_resource, 2, 4, 0,
- "Return the value of ATTRIBUTE, of class CLASS, from the X defaults database.\n\
-This uses `INSTANCE.ATTRIBUTE' as the key and `Emacs.CLASS' as the\n\
-class, where INSTANCE is the name under which Emacs was invoked, or\n\
-the name specified by the `-name' or `-rn' command-line arguments.\n\
-\n\
-The optional arguments COMPONENT and SUBCLASS add to the key and the\n\
-class, respectively. You must specify both of them or neither.\n\
-If you specify them, the key is `INSTANCE.COMPONENT.ATTRIBUTE'\n\
-and the class is `Emacs.CLASS.SUBCLASS'.")
+ 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;
{
}
\f
DEFUN ("x-parse-geometry", Fx_parse_geometry, Sx_parse_geometry, 1, 1, 0,
- "Parse an X-style geometry string STRING.\n\
-Returns an alist of the form ((top . TOP), (left . LEFT) ... ).\n\
-The properties returned may include `top', `left', `height', and `width'.\n\
-The value of `left' or `top' may be an integer,\n\
-or a list (+ N) meaning N pixels relative to top/left corner,\n\
-or a list (- N) meaning -N pixels relative to bottom/right corner.")
+ 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;
{
: 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)));
- f->output_data.w32->flags_areas_extra
- = FRAME_FLAGS_AREA_WIDTH (f);
+
+ 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);
window_prompting |= PPosition;
}
+ if (f->output_data.w32->want_fullscreen != FULLSCREEN_NONE)
+ {
+ int left, top;
+ int width, height;
+
+ /* 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;
+ }
+
return window_prompting;
}
{
PAINTSTRUCT paintStruct;
RECT update_rect;
+ bzero (&update_rect, sizeof (update_rect));
f = x_window_to_frame (dpyinfo, hwnd);
if (f == 0)
/* MSDN Docs say not to call BeginPaint if GetUpdateRect
fails. Apparently this can happen under some
circumstances. */
- if (!w32_strict_painting || GetUpdateRect (hwnd, &update_rect, FALSE))
+ if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
{
enter_crit ();
BeginPaint (hwnd, &paintStruct);
- if (w32_strict_painting)
- /* The rectangles returned by GetUpdateRect and BeginPaint
- do not always match. GetUpdateRect seems to be the
- more reliable of the two. */
- wmsg.rect = update_rect;
- else
- wmsg.rect = paintStruct.rcPaint;
+ /* The rectangles returned by GetUpdateRect and BeginPaint
+ do not always match. Play it safe by assuming both areas
+ are invalid. */
+ UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
#if defined (W32_DEBUG_DISPLAY)
DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
}
return 0;
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP:
+ if (w32_pass_extra_mouse_buttons_to_system)
+ goto dflt;
+ /* else fall through and process them. */
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
handle_plain_button:
BOOL up;
int button;
- if (parse_button (msg, &button, &up))
+ if (parse_button (msg, HIWORD (wParam), &button, &up))
{
if (up) ReleaseCapture ();
else SetCapture (hwnd);
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
- return 0;
- case WM_VSCROLL:
+ /* Need to return true for XBUTTON messages, false for others,
+ to indicate that we processed the message. */
+ return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
+
case WM_MOUSEMOVE:
+ /* If the mouse has just moved into the frame, start tracking
+ it, so we will be notified when it leaves the frame. Mouse
+ tracking only works under W98 and NT4 and later. On earlier
+ versions, there is no way of telling when the mouse leaves the
+ frame, so we just have to put up with help-echo and mouse
+ highlighting remaining while the frame is not active. */
+ if (track_mouse_event_fn && !track_mouse_window)
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof (tme);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+
+ track_mouse_event_fn (&tme);
+ track_mouse_window = hwnd;
+ }
+ case WM_VSCROLL:
if (XINT (Vw32_mouse_move_interval) <= 0
|| (msg == WM_MOUSEMOVE && button_state == 0))
{
KillTimer (hwnd, mouse_move_timer);
mouse_move_timer = 0;
}
+ else if (wParam == menu_free_timer)
+ {
+ KillTimer (hwnd, menu_free_timer);
+ menu_free_timer = 0;
+ f = x_window_to_frame (dpyinfo, hwnd);
+ if (!f->output_data.w32->menu_command_in_progress)
+ {
+ /* Free memory used by owner-drawn and help-echo strings. */
+ w32_free_menu_strings (hwnd);
+ f->output_data.w32->menubar_active = 0;
+ }
+ }
return 0;
case WM_NCACTIVATE:
case WM_EXITMENULOOP:
f = x_window_to_frame (dpyinfo, hwnd);
- /* Indicate that menubar can be modified again. */
- if (f)
- f->output_data.w32->menubar_active = 0;
+ /* If a menu command is not already in progress, check again
+ after a short delay, since Windows often (always?) sends the
+ WM_EXITMENULOOP before the corresponding WM_COMMAND message. */
+ if (f && !f->output_data.w32->menu_command_in_progress)
+ menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
goto dflt;
case WM_MENUSELECT:
- wmsg.dwModifiers = w32_get_modifiers ();
- my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
+ /* Direct handling of help_echo in menus. Should be safe now
+ that we generate the help_echo by placing a help event in the
+ keyboard buffer. */
+ {
+ HMENU menu = (HMENU) lParam;
+ UINT menu_item = (UINT) LOWORD (wParam);
+ UINT flags = (UINT) HIWORD (wParam);
+
+ w32_menu_display_help (hwnd, menu, menu_item, flags);
+ }
return 0;
case WM_MEASUREITEM:
goto dflt;
#endif
+ case WM_MOUSELEAVE:
+ /* No longer tracking mouse. */
+ track_mouse_window = NULL;
+
case WM_ACTIVATEAPP:
case WM_ACTIVATE:
case WM_WINDOWPOSCHANGED:
/* Relinquish the system caret. */
if (w32_system_caret_hwnd)
{
- DestroyCaret ();
+ w32_visible_system_caret_hwnd = NULL;
w32_system_caret_hwnd = NULL;
+ DestroyCaret ();
+ }
+ goto command;
+ case WM_COMMAND:
+ f = x_window_to_frame (dpyinfo, hwnd);
+ if (f && HIWORD (wParam) == 0)
+ {
+ f->output_data.w32->menu_command_in_progress = 1;
+ if (menu_free_timer)
+ {
+ KillTimer (hwnd, menu_free_timer);
+ menu_free_timer = 0;
+ }
}
case WM_MOVE:
case WM_SIZE:
- case WM_COMMAND:
command:
wmsg.dwModifiers = w32_get_modifiers ();
my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
return 0;
case WM_WINDOWPOSCHANGING:
+ /* Don't restrict the sizing of tip frames. */
+ if (hwnd == tip_window)
+ return 0;
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
DragAcceptFiles ((HWND) wParam, FALSE);
return DestroyWindow ((HWND) wParam);
+ case WM_EMACS_HIDE_CARET:
+ return HideCaret (hwnd);
+
+ case WM_EMACS_SHOW_CARET:
+ return ShowCaret (hwnd);
+
case WM_EMACS_DESTROY_CARET:
w32_system_caret_hwnd = NULL;
+ w32_visible_system_caret_hwnd = NULL;
return DestroyCaret ();
case WM_EMACS_TRACK_CARET:
/* If there is currently no system caret, create one. */
if (w32_system_caret_hwnd == NULL)
{
+ /* Use the default caret width, and avoid changing it
+ unneccesarily, as it confuses screen reader software. */
w32_system_caret_hwnd = hwnd;
- CreateCaret (hwnd, NULL, w32_system_caret_width,
+ CreateCaret (hwnd, NULL, 0,
w32_system_caret_height);
}
- return SetCaretPos (w32_system_caret_x, w32_system_caret_y);
+
+ if (!SetCaretPos (w32_system_caret_x, w32_system_caret_y))
+ return 0;
+ /* Ensure visible caret gets turned on when requested. */
+ else if (w32_use_visible_system_caret
+ && w32_visible_system_caret_hwnd != hwnd)
+ {
+ w32_visible_system_caret_hwnd = hwnd;
+ return ShowCaret (hwnd);
+ }
+ /* Ensure visible caret gets turned off when requested. */
+ else if (!w32_use_visible_system_caret
+ && w32_visible_system_caret_hwnd)
+ {
+ w32_visible_system_caret_hwnd = NULL;
+ return HideCaret (hwnd);
+ }
+ else
+ return 1;
case WM_EMACS_TRACKPOPUPMENU:
{
GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
}
+
+/* Create a tooltip window. Unlike my_create_window, we do not do this
+ indirectly via the Window thread, as we do not need to process Window
+ messages for the tooltip. Creating tooltips indirectly also creates
+ deadlocks when tooltips are created for menu items. */
+void
+my_create_tip_window (f)
+ struct frame *f;
+{
+ RECT rect;
+
+ rect.left = rect.top = 0;
+ rect.right = PIXEL_WIDTH (f);
+ rect.bottom = PIXEL_HEIGHT (f);
+
+ AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
+ FRAME_EXTERNAL_MENU_BAR (f));
+
+ tip_window = FRAME_W32_WINDOW (f)
+ = CreateWindow (EMACS_CLASS,
+ f->namebuf,
+ f->output_data.w32->dwStyle,
+ f->output_data.w32->left_pos,
+ f->output_data.w32->top_pos,
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ FRAME_W32_WINDOW (SELECTED_FRAME ()), /* owner */
+ NULL,
+ hinst,
+ NULL);
+
+ if (tip_window)
+ {
+ SetWindowLong (tip_window, WND_FONTWIDTH_INDEX, FONT_WIDTH (f->output_data.w32->font));
+ SetWindowLong (tip_window, WND_LINEHEIGHT_INDEX, f->output_data.w32->line_height);
+ SetWindowLong (tip_window, WND_BORDER_INDEX, f->output_data.w32->internal_border_width);
+ SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
+
+ /* Tip frames have no scrollbars. */
+ SetWindowLong (tip_window, WND_SCROLLBAR_INDEX, 0);
+
+ /* Do this to discard the default setting specified by our parent. */
+ ShowWindow (tip_window, SW_HIDE);
+ }
+}
+
+
/* Create and set up the w32 window for frame F. */
static void
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1, 1, 0,
- "Make a new window, which is called a \"frame\" in Emacs terms.\n\
-Returns an Emacs frame object.\n\
-ALIST is an alist of frame parameters.\n\
-If the parameters specify that the frame should not have a minibuffer,\n\
-and do not specify a specific minibuffer window to use,\n\
-then `default-minibuffer-frame' must be a frame whose minibuffer can\n\
-be shared by the new frame.\n\
-\n\
-This function is an internal primitive--use `make-frame' instead.")
+ doc: /* Make a new window, which is called a \"frame\" in Emacs terms.
+Returns an Emacs frame object.
+ALIST is an alist of frame parameters.
+If the parameters specify that the frame should not have a minibuffer,
+and do not specify a specific minibuffer window to use,
+then `default-minibuffer-frame' must be a frame whose minibuffer can
+be shared by the new frame.
+
+This function is an internal primitive--use `make-frame' instead. */)
(parms)
Lisp_Object parms;
{
"screenGamma", "ScreenGamma", RES_TYPE_FLOAT);
x_default_parameter (f, parms, Qline_spacing, Qnil,
"lineSpacing", "LineSpacing", RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qleft_fringe, Qnil,
+ "leftFringe", "LeftFringe", RES_TYPE_NUMBER);
+ x_default_parameter (f, parms, Qright_fringe, Qnil,
+ "rightFringe", "RightFringe", RES_TYPE_NUMBER);
/* Init faces before x_default_parameter is called for scroll-bar
x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
"menuBar", "MenuBar", RES_TYPE_NUMBER);
- x_default_parameter (f, parms, Qtool_bar_lines, make_number (0),
+ x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
"toolBar", "ToolBar", RES_TYPE_NUMBER);
+
x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
"bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
x_default_parameter (f, parms, Qtitle, Qnil,
"title", "Title", RES_TYPE_STRING);
+ x_default_parameter (f, parms, Qfullscreen, Qnil,
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
{
int margin, relief, bar_height;
- relief = (tool_bar_button_relief > 0
+ relief = (tool_bar_button_relief >= 0
? tool_bar_button_relief
: DEFAULT_TOOL_BAR_BUTTON_RELIEF);
x_wm_set_size_hint (f, window_prompting, 0);
UNBLOCK_INPUT;
+ /* Avoid a bug that causes the new frame to never become visible if
+ an echo area message is displayed during the following call1. */
+ specbind(Qredisplay_dont_pause, Qt);
+
/* Set up faces after all frame parameters are known. This call
also merges in face attributes specified for new frames. If we
don't do this, the `menu' face for instance won't have the right
}
DEFUN ("w32-focus-frame", Fw32_focus_frame, Sw32_focus_frame, 1, 1, 0,
- "Give FRAME input focus, raising to foreground if necessary.")
+ doc: /* Give FRAME input focus, raising to foreground if necessary. */)
(frame)
Lisp_Object frame;
{
ended up with. */
return NULL;
+ /* Specify anti-aliasing to prevent Cleartype fonts being used,
+ since those fonts leave garbage behind. */
+ lf.lfQuality = ANTIALIASED_QUALITY;
+
font = (XFontStruct *) xmalloc (sizeof (XFontStruct));
bzero (font, sizeof (*font));
/* SJIS fonts need to be set to type 4, all others seem to work as
type FONT_ENCODING_NOT_DECIDED. */
encoding = strrchr (fontp->name, '-');
- if (encoding && stricmp (encoding+1, "sjis") == 0)
+ if (encoding && strnicmp (encoding+1, "sjis", 4) == 0)
fontp->encoding[1] = 4;
else
fontp->encoding[1] = FONT_ENCODING_NOT_DECIDED;
/* Set global flag fonts_changed_p to non-zero if the font loaded
has a character with a smaller width than any other character
- before, or if the font loaded has a smalle>r height than any
+ before, or if the font loaded has a smaller height than any
other font loaded before. If this happens, it will make a
glyph matrix reallocation necessary. */
- fonts_changed_p = x_compute_min_glyph_bounds (f);
+ fonts_changed_p |= x_compute_min_glyph_bounds (f);
UNBLOCK_INPUT;
return fontp;
}
w32_charset = Fcar (Fcdr (this_entry));
- // Translate Lisp symbol to number.
+ /* Translate Lisp symbol to number. */
if (w32_charset == Qw32_charset_ansi)
return ANSI_CHARSET;
if (w32_charset == Qw32_charset_symbol)
best_match = x_charset;
/* If this is an ISO codepage, and the best so far isn't,
then this is better. */
- else if (stricmp (best_match, "iso") != 0
- && stricmp (x_charset, "iso") == 0)
+ else if (strnicmp (best_match, "iso", 3) != 0
+ && strnicmp (x_charset, "iso", 3) == 0)
best_match = x_charset;
/* If both are ISO8859 codepages, choose the one with the
lowest number in the encoding field. */
- else if (stricmp (best_match, "iso8859-") == 0
- && stricmp (x_charset, "iso8859-") == 0)
+ else if (strnicmp (best_match, "iso8859-", 8) == 0
+ && strnicmp (x_charset, "iso8859-", 8) == 0)
{
int best_enc = atoi (best_match + 8);
int this_enc = atoi (x_charset + 8);
}
-/* Get the Windows codepage corresponding to the specified font. The
- charset info in the font name is used to look up
- w32-charset-to-codepage-alist. */
-int
-w32_codepage_for_font (char *fontname)
+/* Return all the X charsets that map to a font. */
+static Lisp_Object
+w32_to_all_x_charsets (fncharset)
+ int fncharset;
{
- Lisp_Object codepage, entry;
- char *charset_str, *charset, *end;
-
- if (NILP (Vw32_charset_info_alist))
- return CP_DEFAULT;
+ static char buf[32];
+ Lisp_Object charset_type;
+ Lisp_Object retval = Qnil;
- /* Extract charset part of font string. */
- charset = xlfd_charset_of_font (fontname);
+ switch (fncharset)
+ {
+ case ANSI_CHARSET:
+ /* Handle startup case of w32-charset-info-alist not
+ being set up yet. */
+ if (NILP(Vw32_charset_info_alist))
+ return Fcons (build_string ("iso8859-1"), Qnil);
- if (!charset)
- return CP_UNKNOWN;
+ charset_type = Qw32_charset_ansi;
+ break;
+ case DEFAULT_CHARSET:
+ charset_type = Qw32_charset_default;
+ break;
+ case SYMBOL_CHARSET:
+ charset_type = Qw32_charset_symbol;
+ break;
+ case SHIFTJIS_CHARSET:
+ charset_type = Qw32_charset_shiftjis;
+ break;
+ case HANGEUL_CHARSET:
+ charset_type = Qw32_charset_hangeul;
+ break;
+ case GB2312_CHARSET:
+ charset_type = Qw32_charset_gb2312;
+ break;
+ case CHINESEBIG5_CHARSET:
+ charset_type = Qw32_charset_chinesebig5;
+ break;
+ case OEM_CHARSET:
+ charset_type = Qw32_charset_oem;
+ break;
- charset_str = (char *) alloca (strlen (charset) + 1);
- strcpy (charset_str, charset);
+ /* More recent versions of Windows (95 and NT4.0) define more
+ character sets. */
+#ifdef EASTEUROPE_CHARSET
+ case EASTEUROPE_CHARSET:
+ charset_type = Qw32_charset_easteurope;
+ break;
+ case TURKISH_CHARSET:
+ charset_type = Qw32_charset_turkish;
+ break;
+ case BALTIC_CHARSET:
+ charset_type = Qw32_charset_baltic;
+ break;
+ case RUSSIAN_CHARSET:
+ charset_type = Qw32_charset_russian;
+ break;
+ case ARABIC_CHARSET:
+ charset_type = Qw32_charset_arabic;
+ break;
+ case GREEK_CHARSET:
+ charset_type = Qw32_charset_greek;
+ break;
+ case HEBREW_CHARSET:
+ charset_type = Qw32_charset_hebrew;
+ break;
+ case VIETNAMESE_CHARSET:
+ charset_type = Qw32_charset_vietnamese;
+ break;
+ case THAI_CHARSET:
+ charset_type = Qw32_charset_thai;
+ break;
+ case MAC_CHARSET:
+ charset_type = Qw32_charset_mac;
+ break;
+ case JOHAB_CHARSET:
+ charset_type = Qw32_charset_johab;
+ break;
+#endif
-#if 0
- /* Remove leading "*-". */
- if (strncmp ("*-", charset_str, 2) == 0)
- charset = charset_str + 2;
- else
+#ifdef UNICODE_CHARSET
+ case UNICODE_CHARSET:
+ charset_type = Qw32_charset_unicode;
+ break;
#endif
- charset = charset_str;
+ default:
+ /* Encode numerical value of unknown charset. */
+ sprintf (buf, "*-#%u", fncharset);
+ return Fcons (build_string (buf), Qnil);
+ }
+
+ {
+ Lisp_Object rest;
+ /* Look through w32-charset-info-alist for the character set.
+ Only return charsets for codepages which are installed.
- /* Stop match at wildcard (including preceding '-'). */
- if (end = strchr (charset, '*'))
+ Format of each entry in Vw32_charset_info_alist is
+ (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE)).
+ */
+ for (rest = Vw32_charset_info_alist; CONSP (rest); rest = XCDR (rest))
{
- if (end > charset && *(end-1) == '-')
- end--;
- *end = '\0';
+ Lisp_Object x_charset;
+ Lisp_Object w32_charset;
+ Lisp_Object codepage;
+
+ Lisp_Object this_entry = XCAR (rest);
+
+ /* Skip invalid entries in alist. */
+ if (!CONSP (this_entry) || !STRINGP (XCAR (this_entry))
+ || !CONSP (XCDR (this_entry))
+ || !SYMBOLP (XCAR (XCDR (this_entry))))
+ continue;
+
+ x_charset = XCAR (this_entry);
+ w32_charset = XCAR (XCDR (this_entry));
+ codepage = XCDR (XCDR (this_entry));
+
+ /* Look for Same charset and a valid codepage (or non-int
+ which means ignore). */
+ if (w32_charset == charset_type
+ && (!INTEGERP (codepage) || codepage == CP_DEFAULT
+ || IsValidCodePage (XINT (codepage))))
+ {
+ retval = Fcons (x_charset, retval);
+ }
+ }
+
+ /* If no match, encode the numeric value. */
+ if (NILP (retval))
+ {
+ sprintf (buf, "*-#%u", fncharset);
+ return Fcons (build_string (buf), Qnil);
+ }
+
+ return retval;
+ }
+}
+
+/* Get the Windows codepage corresponding to the specified font. The
+ charset info in the font name is used to look up
+ w32-charset-to-codepage-alist. */
+int
+w32_codepage_for_font (char *fontname)
+{
+ Lisp_Object codepage, entry;
+ char *charset_str, *charset, *end;
+
+ if (NILP (Vw32_charset_info_alist))
+ return CP_DEFAULT;
+
+ /* Extract charset part of font string. */
+ charset = xlfd_charset_of_font (fontname);
+
+ if (!charset)
+ return CP_UNKNOWN;
+
+ charset_str = (char *) alloca (strlen (charset) + 1);
+ strcpy (charset_str, charset);
+
+#if 0
+ /* Remove leading "*-". */
+ if (strncmp ("*-", charset_str, 2) == 0)
+ charset = charset_str + 2;
+ else
+#endif
+ charset = charset_str;
+
+ /* Stop match at wildcard (including preceding '-'). */
+ if (end = strchr (charset, '*'))
+ {
+ if (end > charset && *(end-1) == '-')
+ end--;
+ *end = '\0';
}
entry = Fassoc (build_string(charset), Vw32_charset_info_alist);
char height_dpi[8];
char width_pixels[8];
char *fontname_dash;
- int display_resy = one_w32_display_info.resy;
- int display_resx = one_w32_display_info.resx;
+ int display_resy = (int) one_w32_display_info.resy;
+ int display_resx = (int) one_w32_display_info.resx;
int bufsz;
struct coding_system coding;
else
fonttype = "unknown";
- setup_coding_system (Fcheck_coding_system (Vw32_system_coding_system),
+ setup_coding_system (Fcheck_coding_system (Vlocale_coding_system),
&coding);
coding.src_multibyte = 0;
coding.dst_multibyte = 1;
char name[50], weight[20], slant, pitch, pixels[10], height[10],
width[10], resy[10], remainder[50];
char * encoding;
- int dpi = one_w32_display_info.resy;
+ int dpi = (int) one_w32_display_info.resy;
fields = sscanf (lpxstr,
"-%*[^-]-%49[^-]-%19[^-]-%c-%*[^-]-%*[^-]-%9[^-]-%9[^-]-%*[^-]-%9[^-]-%c-%9[^-]-%49s",
unsigned char *buf;
setup_coding_system
- (Fcheck_coding_system (Vw32_system_coding_system), &coding);
+ (Fcheck_coding_system (Vlocale_coding_system), &coding);
coding.src_multibyte = 1;
coding.dst_multibyte = 1;
bufsize = encoding_buffer_size (&coding, strlen (name));
LOGFONT logfont;
XFontStruct *size_ref;
Lisp_Object *pattern;
+ Lisp_Object list;
Lisp_Object *tail;
} enumfont_t;
+
+static void
+enum_font_maybe_add_to_list (enumfont_t *, LOGFONT *, char *, Lisp_Object);
+
+
static int CALLBACK
enum_font_cb2 (lplf, lptm, FontType, lpef)
ENUMLOGFONT * lplf;
int FontType;
enumfont_t * lpef;
{
- /* Ignore struck out, underlined and vertical versions of fonts. */
- if (lplf->elfLogFont.lfStrikeOut || lplf->elfLogFont.lfUnderline
- || lplf->elfLogFont.lfEscapement != 0
- || lplf->elfLogFont.lfOrientation != 0)
+ /* Ignore struck out and underlined versions of fonts. */
+ if (lplf->elfLogFont.lfStrikeOut || lplf->elfLogFont.lfUnderline)
+ return 1;
+
+ /* Only return fonts with names starting with @ if they were
+ explicitly specified, since Microsoft uses an initial @ to
+ denote fonts for vertical writing, without providing a more
+ convenient way of identifying them. */
+ if (lplf->elfLogFont.lfFaceName[0] == '@'
+ && lpef->logfont.lfFaceName[0] != '@')
return 1;
/* Check that the character set matches if it was specified */
lplf->elfLogFont.lfCharSet != lpef->logfont.lfCharSet)
return 1;
+ if (FontType == RASTER_FONTTYPE)
+ {
+ /* DBCS raster fonts have problems displaying, so skip them. */
+ int charset = lplf->elfLogFont.lfCharSet;
+ if (charset == SHIFTJIS_CHARSET
+ || charset == HANGEUL_CHARSET
+ || charset == CHINESEBIG5_CHARSET
+ || charset == GB2312_CHARSET
+#ifdef JOHAB_CHARSET
+ || charset == JOHAB_CHARSET
+#endif
+ )
+ return 1;
+ }
+
{
char buf[100];
Lisp_Object width = Qnil;
+ Lisp_Object charset_list = Qnil;
char *charset = NULL;
/* Truetype fonts do not report their true metrics until loaded */
{
charset = xlfd_charset_of_font (XSTRING(*(lpef->pattern))->data);
- /* Ensure that charset is valid for this font. */
- if (charset
- && (x_to_w32_charset (charset) != lplf->elfLogFont.lfCharSet))
- charset = NULL;
+ /* We already checked charsets above, but DEFAULT_CHARSET
+ slipped through. So only allow exact matches for DEFAULT_CHARSET. */
+ if (charset
+ && strncmp (charset, "*-*", 3) != 0
+ && lpef->logfont.lfCharSet == DEFAULT_CHARSET
+ && strcmp (charset, w32_to_x_charset (DEFAULT_CHARSET)) != 0)
+ return 1;
}
- /* TODO: List all relevant charsets if charset not specified. */
- if (!w32_to_x_font (&(lplf->elfLogFont), buf, 100, charset))
- return 0;
+ if (charset)
+ charset_list = Fcons (build_string (charset), Qnil);
+ else
+ charset_list = w32_to_all_x_charsets (lplf->elfLogFont.lfCharSet);
- if (NILP (*(lpef->pattern))
- || w32_font_match (buf, XSTRING (*(lpef->pattern))->data))
+ /* Loop through the charsets. */
+ for ( ; CONSP (charset_list); charset_list = Fcdr (charset_list))
{
- *lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil);
- lpef->tail = &(XCDR (*lpef->tail));
- lpef->numFonts++;
+ Lisp_Object this_charset = Fcar (charset_list);
+ charset = XSTRING (this_charset)->data;
+
+ /* List bold and italic variations if w32-enable-synthesized-fonts
+ is non-nil and this is a plain font. */
+ if (w32_enable_synthesized_fonts
+ && lplf->elfLogFont.lfWeight == FW_NORMAL
+ && lplf->elfLogFont.lfItalic == FALSE)
+ {
+ enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+ charset, width);
+ /* bold. */
+ lplf->elfLogFont.lfWeight = FW_BOLD;
+ enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+ charset, width);
+ /* bold italic. */
+ lplf->elfLogFont.lfItalic = TRUE;
+ enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+ charset, width);
+ /* italic. */
+ lplf->elfLogFont.lfWeight = FW_NORMAL;
+ enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+ charset, width);
+ }
+ else
+ enum_font_maybe_add_to_list (lpef, &(lplf->elfLogFont),
+ charset, width);
}
}
return 1;
}
+static void
+enum_font_maybe_add_to_list (lpef, logfont, match_charset, width)
+ enumfont_t * lpef;
+ LOGFONT * logfont;
+ char * match_charset;
+ Lisp_Object width;
+{
+ char buf[100];
+
+ if (!w32_to_x_font (logfont, buf, 100, match_charset))
+ return;
+
+ if (NILP (*(lpef->pattern))
+ || w32_font_match (buf, XSTRING (*(lpef->pattern))->data))
+ {
+ /* Check if we already listed this font. This may happen if
+ w32_enable_synthesized_fonts is non-nil, and there are real
+ bold and italic versions of the font. */
+ Lisp_Object font_name = build_string (buf);
+ if (NILP (Fmember (font_name, lpef->list)))
+ {
+ *lpef->tail = Fcons (Fcons (build_string (buf), width), Qnil);
+ lpef->tail = &(XCDR (*lpef->tail));
+ lpef->numFonts++;
+ }
+ }
+}
+
+
static int CALLBACK
enum_font_cb1 (lplf, lptm, FontType, lpef)
ENUMLOGFONT * lplf;
return newlist;
}
-static Lisp_Object w32_list_synthesized_fonts (FRAME_PTR f,
- Lisp_Object pattern,
- int size, int max_names);
/* Return a list of names of available fonts matching PATTERN on frame
F. If SIZE is not 0, it is the size (maximum bound width) of fonts
/* At first, put PATTERN in the cache. */
list = Qnil;
ef.pattern = &tpat;
+ ef.list = list;
ef.tail = &list;
ef.numFonts = 0;
newlist = Fnconc(2, combined);
}
- /* If we can't find a font that matches, check if Windows would be
- able to synthesize it from a different style. */
- if (NILP (newlist) && !NILP (Vw32_enable_synthesized_fonts))
- newlist = w32_list_synthesized_fonts (f, pattern, size, maxnames);
-
return newlist;
}
-static Lisp_Object
-w32_list_synthesized_fonts (f, pattern, size, max_names)
- FRAME_PTR f;
- Lisp_Object pattern;
- int size;
- int max_names;
-{
- int fields;
- char *full_pattn, *new_pattn, foundary[50], family[50], *pattn_part2;
- char style[20], slant;
- Lisp_Object matches, tem, synthed_matches = Qnil;
-
- full_pattn = XSTRING (pattern)->data;
-
- pattn_part2 = alloca (XSTRING (pattern)->size + 1);
- /* Allow some space for wildcard expansion. */
- new_pattn = alloca (XSTRING (pattern)->size + 100);
-
- fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%19[^-]-%c-%s",
- foundary, family, style, &slant, pattn_part2);
- if (fields == EOF || fields < 5)
- return Qnil;
-
- /* If the style and slant are wildcards already there is no point
- checking again (and we don't want to keep recursing). */
- if (*style == '*' && slant == '*')
- return Qnil;
-
- sprintf (new_pattn, "-%s-%s-*-*-%s", foundary, family, pattn_part2);
-
- matches = w32_list_fonts (f, build_string (new_pattn), size, max_names);
-
- for ( ; CONSP (matches); matches = XCDR (matches))
- {
- tem = XCAR (matches);
- if (!STRINGP (tem))
- continue;
-
- full_pattn = XSTRING (tem)->data;
- fields = sscanf (full_pattn, "-%49[^-]-%49[^-]-%*[^-]-%*c-%s",
- foundary, family, pattn_part2);
- if (fields == EOF || fields < 3)
- continue;
-
- sprintf (new_pattn, "-%s-%s-%s-%c-%s", foundary, family, style,
- slant, pattn_part2);
-
- synthed_matches = Fcons (build_string (new_pattn),
- synthed_matches);
- }
-
- return synthed_matches;
-}
-
/* Return a pointer to struct font_info of font FONT_IDX of frame F. */
struct font_info *
DEFUN ("w32-find-bdf-fonts", Fw32_find_bdf_fonts, Sw32_find_bdf_fonts,
1, 1, 0,
- "Return a list of BDF fonts in DIR, suitable for appending to\n\
-w32-bdf-filename-alist. Fonts which do not contain an xlfd description\n\
-will not be included in the list. DIR may be a list of directories.")
+ doc: /* Return a list of BDF fonts in DIR.
+The list is suitable for appending to w32-bdf-filename-alist. Fonts
+which do not contain an xlfd description will not be included in the
+list. DIR may be a list of directories. */)
(directory)
Lisp_Object directory;
{
\f
DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
- "Internal function called by `color-defined-p', which see.")
+ doc: /* Internal function called by `color-defined-p', which see. */)
(color, frame)
Lisp_Object color, frame;
{
}
DEFUN ("xw-color-values", Fxw_color_values, Sxw_color_values, 1, 2, 0,
- "Internal function called by `color-values', which see.")
+ doc: /* Internal function called by `color-values', which see. */)
(color, frame)
Lisp_Object color, frame;
{
}
DEFUN ("xw-display-color-p", Fxw_display_color_p, Sxw_display_color_p, 0, 1, 0,
- "Internal function called by `display-color-p', which see.")
+ doc: /* Internal function called by `display-color-p', which see. */)
(display)
Lisp_Object display;
{
return Qt;
}
-DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p, Sx_display_grayscale_p,
- 0, 1, 0,
- "Return t if the X display supports shades of gray.\n\
-Note that color displays do support shades of gray.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+DEFUN ("x-display-grayscale-p", Fx_display_grayscale_p,
+ Sx_display_grayscale_p, 0, 1, 0,
+ doc: /* Return t if the X display supports shades of gray.
+Note that color displays do support shades of gray.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
return Qt;
}
-DEFUN ("x-display-pixel-width", Fx_display_pixel_width, Sx_display_pixel_width,
- 0, 1, 0,
- "Returns the width in pixels of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+DEFUN ("x-display-pixel-width", Fx_display_pixel_width,
+ Sx_display_pixel_width, 0, 1, 0,
+ doc: /* Returns the width in pixels of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-pixel-height", Fx_display_pixel_height,
- Sx_display_pixel_height, 0, 1, 0,
- "Returns the height in pixels of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ Sx_display_pixel_height, 0, 1, 0,
+ doc: /* Returns the height in pixels of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes,
- 0, 1, 0,
- "Returns the number of bitplanes of the display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ 0, 1, 0,
+ doc: /* Returns the number of bitplanes of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-color-cells", Fx_display_color_cells, Sx_display_color_cells,
- 0, 1, 0,
- "Returns the number of color cells of the display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ 0, 1, 0,
+ doc: /* Returns the number of color cells of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
else
cap = GetDeviceCaps (hdc,NUMCOLORS);
+ /* We force 24+ bit depths to 24-bit, both to prevent an overflow
+ and because probably is more meaningful on Windows anyway */
if (cap < 0)
- cap = 1 << (dpyinfo->n_planes * dpyinfo->n_cbits);
+ cap = 1 << min(dpyinfo->n_planes * dpyinfo->n_cbits, 24);
ReleaseDC (dpyinfo->root_window, hdc);
DEFUN ("x-server-max-request-size", Fx_server_max_request_size,
Sx_server_max_request_size,
- 0, 1, 0,
- "Returns the maximum request size of the server of display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ 0, 1, 0,
+ doc: /* Returns the maximum request size of the server of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-server-vendor", Fx_server_vendor, Sx_server_vendor, 0, 1, 0,
- "Returns the vendor ID string of the W32 system (Microsoft).\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ doc: /* Returns the vendor ID string of the W32 system (Microsoft).
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-server-version", Fx_server_version, Sx_server_version, 0, 1, 0,
- "Returns the version numbers of the server of display DISPLAY.\n\
-The value is a list of three integers: the major and minor\n\
-version numbers, and the vendor-specific release\n\
-number. See also the function `x-server-vendor'.\n\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ doc: /* Returns the version numbers of the server of DISPLAY.
+The value is a list of three integers: the major and minor
+version numbers, and the vendor-specific release
+number. See also the function `x-server-vendor'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
- "Returns the number of screens on the server of display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ doc: /* Returns the number of screens on the server of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
return make_number (1);
}
-DEFUN ("x-display-mm-height", Fx_display_mm_height, Sx_display_mm_height, 0, 1, 0,
- "Returns the height in millimeters of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+DEFUN ("x-display-mm-height", Fx_display_mm_height,
+ Sx_display_mm_height, 0, 1, 0,
+ doc: /* Returns the height in millimeters of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
- "Returns the width in millimeters of the X display DISPLAY.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ doc: /* Returns the width in millimeters of DISPLAY.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
- Sx_display_backing_store, 0, 1, 0,
- "Returns an indication of whether display DISPLAY does backing store.\n\
-The value may be `always', `when-mapped', or `not-useful'.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ Sx_display_backing_store, 0, 1, 0,
+ doc: /* Returns an indication of whether DISPLAY does backing store.
+The value may be `always', `when-mapped', or `not-useful'.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-visual-class", Fx_display_visual_class,
- Sx_display_visual_class, 0, 1, 0,
- "Returns the visual class of the display DISPLAY.\n\
-The value is one of the symbols `static-gray', `gray-scale',\n\
-`static-color', `pseudo-color', `true-color', or `direct-color'.\n\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ Sx_display_visual_class, 0, 1, 0,
+ doc: /* Returns the visual class of DISPLAY.
+The value is one of the symbols `static-gray', `gray-scale',
+`static-color', `pseudo-color', `true-color', or `direct-color'.
+
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-save-under", Fx_display_save_under,
- Sx_display_save_under, 0, 1, 0,
- "Returns t if the display DISPLAY supports the save-under feature.\n\
-The optional argument DISPLAY specifies which display to ask about.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If omitted or nil, that stands for the selected frame's display.")
+ Sx_display_save_under, 0, 1, 0,
+ doc: /* Returns t if DISPLAY supports the save-under feature.
+The optional argument DISPLAY specifies which display to ask about.
+DISPLAY should be either a frame or a display name (a string).
+If omitted or nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-open-connection", Fx_open_connection, Sx_open_connection,
- 1, 3, 0, "Open a connection to a server.\n\
-DISPLAY is the name of the display to connect to.\n\
-Optional second arg XRM-STRING is a string of resources in xrdb format.\n\
-If the optional third arg MUST-SUCCEED is non-nil,\n\
-terminate Emacs if we can't open the connection.")
+ 1, 3, 0, doc: /* Open a connection to a server.
+DISPLAY is the name of the display to connect to.
+Optional second arg XRM-STRING is a string of resources in xrdb format.
+If the optional third arg MUST-SUCCEED is non-nil,
+terminate Emacs if we can't open the connection. */)
(display, xrm_string, must_succeed)
Lisp_Object display, xrm_string, must_succeed;
{
unsigned char *xrm_option;
struct w32_display_info *dpyinfo;
+ /* If initialization has already been done, return now to avoid
+ overwriting critical parts of one_w32_display_info. */
+ if (w32_in_use)
+ return Qnil;
+
CHECK_STRING (display);
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
DEFUN ("x-close-connection", Fx_close_connection,
Sx_close_connection, 1, 1, 0,
- "Close the connection to DISPLAY's server.\n\
-For DISPLAY, specify either a frame or a display name (a string).\n\
-If DISPLAY is nil, that stands for the selected frame's display.")
+ doc: /* Close the connection to DISPLAY's server.
+For DISPLAY, specify either a frame or a display name (a string).
+If DISPLAY is nil, that stands for the selected frame's display. */)
(display)
Lisp_Object display;
{
}
DEFUN ("x-display-list", Fx_display_list, Sx_display_list, 0, 0, 0,
- "Return the list of display names that Emacs has connections to.")
+ doc: /* Return the list of display names that Emacs has connections to. */)
()
{
Lisp_Object tail, result;
}
DEFUN ("x-synchronize", Fx_synchronize, Sx_synchronize, 1, 2, 0,
- "If ON is non-nil, report errors as soon as the erring request is made.\n\
-If ON is nil, allow buffering of requests.\n\
-This is a noop on W32 systems.\n\
-The optional second argument DISPLAY specifies which display to act on.\n\
-DISPLAY should be either a frame or a display name (a string).\n\
-If DISPLAY is omitted or nil, that stands for the selected frame's display.")
- (on, display)
- Lisp_Object display, on;
+ doc: /* This is a noop on W32 systems. */)
+ (on, display)
+ Lisp_Object display, on;
{
return Qnil;
}
\f
-\f
/***********************************************************************
Image types
***********************************************************************/
/* Keywords. */
extern Lisp_Object QCwidth, QCheight, QCforeground, QCbackground, QCfile;
-extern Lisp_Object QCdata;
-Lisp_Object QCtype, QCascent, QCmargin, QCrelief;
+extern Lisp_Object QCdata, QCtype;
+Lisp_Object QCascent, QCmargin, QCrelief;
Lisp_Object QCconversion, QCcolor_symbols, QCheuristic_mask;
Lisp_Object QCindex, QCmatrix, QCcolor_adjustment, QCmask;
/* Find key in KEYWORDS. Error if not found. */
for (i = 0; i < nkeywords; ++i)
- if (strcmp (keywords[i].name, XSYMBOL (key)->name->data) == 0)
+ if (strcmp (keywords[i].name, XSTRING (SYMBOL_NAME (key))->data) == 0)
break;
if (i == nkeywords)
}
+DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
+ doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
+PIXELS non-nil means return the size in pixels, otherwise return the
+size in canonical character units.
+FRAME is the frame on which the image will be displayed. FRAME nil
+or omitted means use the selected frame. */)
+ (spec, pixels, frame)
+ Lisp_Object spec, pixels, frame;
+{
+ Lisp_Object size;
+
+ size = Qnil;
+ if (valid_image_p (spec))
+ {
+ struct frame *f = check_x_frame (frame);
+ int id = lookup_image (f, spec);
+ struct image *img = IMAGE_FROM_ID (f, id);
+ int width = img->width + 2 * img->hmargin;
+ int height = img->height + 2 * img->vmargin;
+
+ if (NILP (pixels))
+ size = Fcons (make_float ((double) width / CANON_X_UNIT (f)),
+ make_float ((double) height / CANON_Y_UNIT (f)));
+ else
+ size = Fcons (make_number (width), make_number (height));
+ }
+ else
+ error ("Invalid image specification");
+
+ return size;
+}
+
+
+DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
+ doc: /* Return t if image SPEC has a mask bitmap.
+FRAME is the frame on which the image will be displayed. FRAME nil
+or omitted means use the selected frame. */)
+ (spec, frame)
+ Lisp_Object spec, frame;
+{
+ Lisp_Object mask;
+
+ mask = Qnil;
+ if (valid_image_p (spec))
+ {
+ struct frame *f = check_x_frame (frame);
+ int id = lookup_image (f, spec);
+ struct image *img = IMAGE_FROM_ID (f, id);
+ if (img->mask)
+ mask = Qt;
+ }
+ else
+ error ("Invalid image specification");
+
+ return mask;
+}
\f
/***********************************************************************
ascent = height / 2;
}
else
- ascent = height * img->ascent / 100.0;
+ ascent = (int) (height * img->ascent / 100.0);
return ascent;
}
\f
+/* Image background colors. */
+
+/* Find the "best" corner color of a bitmap. XIMG is assumed to a device
+ context with the bitmap selected. */
+static COLORREF
+four_corners_best (ximg, width, height)
+ HDC ximg;
+ unsigned long width, height;
+{
+ COLORREF corners[4], best;
+ int i, best_count;
+
+ /* Get the colors at the corners of ximg. */
+ corners[0] = GetPixel (ximg, 0, 0);
+ corners[1] = GetPixel (ximg, width - 1, 0);
+ corners[2] = GetPixel (ximg, width - 1, height - 1);
+ corners[3] = GetPixel (ximg, 0, height - 1);
+
+ /* Choose the most frequently found color as background. */
+ for (i = best_count = 0; i < 4; ++i)
+ {
+ int j, n;
+
+ for (j = n = 0; j < 4; ++j)
+ if (corners[i] == corners[j])
+ ++n;
+
+ if (n > best_count)
+ best = corners[i], best_count = n;
+ }
+
+ return best;
+}
+
+/* Return the `background' field of IMG. If IMG doesn't have one yet,
+ it is guessed heuristically. If non-zero, XIMG is an existing XImage
+ object to use for the heuristic. */
+
+unsigned long
+image_background (img, f, ximg)
+ struct image *img;
+ struct frame *f;
+ XImage *ximg;
+{
+ if (! img->background_valid)
+ /* IMG doesn't have a background yet, try to guess a reasonable value. */
+ {
+#if 0 /* TODO: Image support. */
+ int free_ximg = !ximg;
+
+ if (! ximg)
+ ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
+ 0, 0, img->width, img->height, ~0, ZPixmap);
+
+ img->background = four_corners_best (ximg, img->width, img->height);
+
+ if (free_ximg)
+ XDestroyImage (ximg);
+
+ img->background_valid = 1;
+#endif
+ }
+
+ return img->background;
+}
+
+/* Return the `background_transparent' field of IMG. If IMG doesn't
+ have one yet, it is guessed heuristically. If non-zero, MASK is an
+ existing XImage object to use for the heuristic. */
+
+int
+image_background_transparent (img, f, mask)
+ struct image *img;
+ struct frame *f;
+ XImage *mask;
+{
+ if (! img->background_transparent_valid)
+ /* IMG doesn't have a background yet, try to guess a reasonable value. */
+ {
+#if 0 /* TODO: Image support. */
+ if (img->mask)
+ {
+ int free_mask = !mask;
+
+ if (! mask)
+ mask = XGetImage (FRAME_X_DISPLAY (f), img->mask,
+ 0, 0, img->width, img->height, ~0, ZPixmap);
+
+ img->background_transparent
+ = !four_corners_best (mask, img->width, img->height);
+
+ if (free_mask)
+ XDestroyImage (mask);
+ }
+ else
+#endif
+ img->background_transparent = 0;
+
+ img->background_transparent_valid = 1;
+ }
+
+ return img->background_transparent;
+}
+
+\f
/***********************************************************************
Helper functions for X image types
***********************************************************************/
+static void x_clear_image_1 P_ ((struct frame *, struct image *, int,
+ int, int));
static void x_clear_image P_ ((struct frame *f, struct image *img));
static unsigned long x_alloc_image_color P_ ((struct frame *f,
struct image *img,
Lisp_Object color_name,
unsigned long dflt));
+
+/* Clear X resources of image IMG on frame F. PIXMAP_P non-zero means
+ free the pixmap if any. MASK_P non-zero means clear the mask
+ pixmap if any. COLORS_P non-zero means free colors allocated for
+ the image, if any. */
+
+static void
+x_clear_image_1 (f, img, pixmap_p, mask_p, colors_p)
+ struct frame *f;
+ struct image *img;
+ int pixmap_p, mask_p, colors_p;
+{
+ if (pixmap_p && img->pixmap)
+ {
+ DeleteObject (img->pixmap);
+ img->pixmap = NULL;
+ img->background_valid = 0;
+ }
+
+ if (mask_p && img->mask)
+ {
+ DeleteObject (img->mask);
+ img->mask = NULL;
+ img->background_transparent_valid = 0;
+ }
+
+ if (colors_p && img->ncolors)
+ {
+#if 0 /* TODO: color table support. */
+ x_free_colors (f, img->colors, img->ncolors);
+#endif
+ xfree (img->colors);
+ img->colors = NULL;
+ img->ncolors = 0;
+ }
+}
+
/* Free X resources of image IMG which is used on frame F. */
static void
struct frame *f;
struct image *img;
{
-#if 0 /* TODO: W32 image support */
-
if (img->pixmap)
{
BLOCK_INPUT;
- XFreePixmap (NULL, img->pixmap);
+ DeleteObject (img->pixmap);
img->pixmap = 0;
UNBLOCK_INPUT;
}
if (img->ncolors)
{
+#if 0 /* TODO: color table support */
+
int class = FRAME_W32_DISPLAY_INFO (f)->visual->class;
/* If display has an immutable color map, freeing colors is not
img->ncolors, 0);
UNBLOCK_INPUT;
}
+#endif
xfree (img->colors);
img->colors = NULL;
img->ncolors = 0;
}
-#endif
}
Lisp_Object color_name;
unsigned long dflt;
{
-#if 0 /* TODO: allocing colors. */
XColor color;
unsigned long result;
else
result = dflt;
return result;
-#endif
- return 0;
}
{
EMACS_TIME t;
unsigned long old;
- int i, any_freed_p = 0;
+ int i, nfreed;
EMACS_GET_TIME (t);
old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
- for (i = 0; i < c->used; ++i)
+ /* Block input so that we won't be interrupted by a SIGIO
+ while being in an inconsistent state. */
+ BLOCK_INPUT;
+
+ for (i = nfreed = 0; i < c->used; ++i)
{
struct image *img = c->images[i];
if (img != NULL
- && (force_p
- || (img->timestamp > old)))
+ && (force_p || (img->timestamp < old)))
{
free_image (f, img);
- any_freed_p = 1;
+ ++nfreed;
}
}
Emacs was iconified for a longer period of time. In that
case, current matrices may still contain references to
images freed above. So, clear these matrices. */
- if (any_freed_p)
+ if (nfreed)
{
- clear_current_matrices (f);
+ Lisp_Object tail, frame;
+
+ FOR_EACH_FRAME (tail, frame)
+ {
+ struct frame *f = XFRAME (frame);
+ if (FRAME_W32_P (f)
+ && FRAME_X_IMAGE_CACHE (f) == c)
+ clear_current_matrices (f);
+ }
+
++windows_or_buffers_changed;
}
+
+ UNBLOCK_INPUT;
}
}
DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
0, 1, 0,
- "Clear the image cache of FRAME.\n\
-FRAME nil or omitted means use the selected frame.\n\
-FRAME t means clear the image caches of all frames.")
+ doc: /* Clear the image cache of FRAME.
+FRAME nil or omitted means use the selected frame.
+FRAME t means clear the image caches of all frames. */)
(frame)
Lisp_Object frame;
{
}
else if (NILP (mask) && found_p && img->mask)
{
- XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
+ DeleteObject (img->mask);
img->mask = NULL;
}
}
else
{
/* Handle image type independent image attributes
- `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF'. */
- Lisp_Object ascent, margin, relief;
+ `:ascent PERCENT', `:margin MARGIN', `:relief RELIEF',
+ `:background COLOR'. */
+ Lisp_Object ascent, margin, relief, bg;
ascent = image_spec_value (spec, QCascent, NULL);
if (INTEGERP (ascent))
img->vmargin += abs (img->relief);
}
+ if (! img->background_valid)
+ {
+ bg = image_spec_value (img->spec, QCbackground, NULL);
+ if (!NILP (bg))
+ {
+ img->background
+ = x_alloc_image_color (f, img, bg,
+ FRAME_BACKGROUND_PIXEL (f));
+ img->background_valid = 1;
+ }
+ }
+
/* Do image transformations and compute masks, unless we
don't have the image yet. */
if (!EQ (*img->type->type, Qpostscript))
W32 support code
***********************************************************************/
-#if 0 /* TODO: W32 specific image code. */
-
static int x_create_x_image_and_pixmap P_ ((struct frame *, int, int, int,
XImage **, Pixmap *));
static void x_destroy_x_image P_ ((XImage *));
/* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
frame F. Set *XIMG and *PIXMAP to the XImage and Pixmap created.
Set (*XIMG)->data to a raster of WIDTH x HEIGHT pixels allocated
- via xmalloc. Print error messages via image_error if an error
- occurs. Value is non-zero if successful. */
+ via xmalloc. DEPTH of zero signifies a 24 bit image, otherwise
+ DEPTH should indicate the bit depth of the image. Print error
+ messages via image_error if an error occurs. Value is non-zero if
+ successful. */
static int
x_create_x_image_and_pixmap (f, width, height, depth, ximg, pixmap)
XImage **ximg;
Pixmap *pixmap;
{
-#if 0 /* TODO: Image support for W32 */
- Display *display = FRAME_W32_DISPLAY (f);
- Screen *screen = FRAME_X_SCREEN (f);
- Window window = FRAME_W32_WINDOW (f);
+ BITMAPINFOHEADER *header;
+ HDC hdc;
+ int scanline_width_bits;
+ int remainder;
+ int palette_colors = 0;
- xassert (interrupt_input_blocked);
+ if (depth == 0)
+ depth = 24;
+
+ if (depth != 1 && depth != 4 && depth != 8
+ && depth != 16 && depth != 24 && depth != 32)
+ {
+ image_error ("Invalid image bit depth specified", Qnil, Qnil);
+ return 0;
+ }
+
+ scanline_width_bits = width * depth;
+ remainder = scanline_width_bits % 32;
+
+ if (remainder)
+ scanline_width_bits += 32 - remainder;
+
+ /* Bitmaps with a depth less than 16 need a palette. */
+ /* BITMAPINFO structure already contains the first RGBQUAD. */
+ if (depth < 16)
+ palette_colors = 1 << depth - 1;
- if (depth <= 0)
- depth = DefaultDepthOfScreen (screen);
- *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
- depth, ZPixmap, 0, NULL, width, height,
- depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
+ *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
if (*ximg == NULL)
{
- image_error ("Unable to allocate X image", Qnil, Qnil);
+ image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
return 0;
}
- /* Allocate image raster. */
- (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
+ header = &((*ximg)->info.bmiHeader);
+ bzero (&((*ximg)->info), sizeof (BITMAPINFO));
+ header->biSize = sizeof (*header);
+ header->biWidth = width;
+ header->biHeight = -height; /* negative indicates a top-down bitmap. */
+ header->biPlanes = 1;
+ header->biBitCount = depth;
+ header->biCompression = BI_RGB;
+ header->biClrUsed = palette_colors;
- /* Allocate a pixmap of the same size. */
- *pixmap = XCreatePixmap (display, window, width, height, depth);
- if (*pixmap == 0)
+ hdc = get_frame_dc (f);
+
+ /* Create a DIBSection and raster array for the bitmap,
+ and store its handle in *pixmap. */
+ *pixmap = CreateDIBSection (hdc, &((*ximg)->info), DIB_RGB_COLORS,
+ &((*ximg)->data), NULL, 0);
+
+ /* Realize display palette and garbage all frames. */
+ release_frame_dc (f, hdc);
+
+ if (*pixmap == NULL)
{
+ DWORD err = GetLastError();
+ Lisp_Object errcode;
+ /* All system errors are < 10000, so the following is safe. */
+ XSETINT (errcode, (int) err);
+ image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
x_destroy_x_image (*ximg);
- *ximg = NULL;
- image_error ("Unable to create X pixmap", Qnil, Qnil);
return 0;
}
-#endif
+
return 1;
}
xassert (interrupt_input_blocked);
if (ximg)
{
- xfree (ximg->data);
+ /* Data will be freed by DestroyObject. */
ximg->data = NULL;
- XDestroyImage (ximg);
+ xfree (ximg);
}
}
XImage *ximg;
Pixmap pixmap;
{
+
+#if TODO /* W32 specific image code. */
GC gc;
-
+
xassert (interrupt_input_blocked);
gc = XCreateGC (NULL, pixmap, 0, NULL);
XPutImage (NULL, pixmap, gc, ximg, 0, 0, 0, 0, width, height);
XFreeGC (NULL, gc);
-}
-
#endif
+}
\f
/***********************************************************************
GCPRO2 (file_found, search_path);
/* Try to find FILE in data-directory, then x-bitmap-file-path. */
- fd = openp (search_path, file, Qnil, &file_found, 0);
+ fd = openp (search_path, file, Qnil, &file_found, Qnil);
if (fd == -1)
file_found = Qnil;
XBM images
***********************************************************************/
+static int xbm_scan P_ ((char **, char *, char *, int *));
static int xbm_load P_ ((struct frame *f, struct image *img));
-static int xbm_load_image_from_file P_ ((struct frame *f, struct image *img,
- Lisp_Object file));
+static int xbm_load_image P_ ((struct frame *f, struct image *img,
+ char *, char *));
static int xbm_image_p P_ ((Lisp_Object object));
-static int xbm_read_bitmap_file_data P_ ((char *, int *, int *,
- unsigned char **));
+static int xbm_read_bitmap_data P_ ((char *, char *, int *, int *,
+ unsigned char **));
+static int xbm_file_p P_ ((Lisp_Object));
/* Indices of image specification fields in xbm_format, below. */
XBM_RELIEF,
XBM_ALGORITHM,
XBM_HEURISTIC_MASK,
+ XBM_MASK,
XBM_LAST
};
{":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
{":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
{":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
- {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
+ {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
+ {":ascent", IMAGE_ASCENT_VALUE, 0},
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
};
/* Structure describing the image type XBM. */
3. a vector of strings or bool-vectors, one for each line of the
bitmap.
+ 4. A string containing an in-memory XBM file. WIDTH and HEIGHT
+ may not be specified in this case because they are defined in the
+ XBM file.
+
Both the file and data forms may contain the additional entries
`:background COLOR' and `:foreground COLOR'. If not present,
foreground and background of the frame on which the image is
- displayed, is used. */
+ displayed is used. */
static int
xbm_image_p (object)
if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
return 0;
}
+ else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
+ {
+ /* In-memory XBM file. */
+ if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
+ return 0;
+ }
else
{
Lisp_Object data;
return 0;
}
- /* Baseline must be a value between 0 and 100 (a percentage). */
- if (kw[XBM_ASCENT].count
- && XFASTINT (kw[XBM_ASCENT].value) > 100)
- return 0;
-
return 1;
}
loop:
/* Skip white space. */
- while (*s < end &&(c = *(*s)++, isspace (c)))
+ while (*s < end && (c = *(*s)++, isspace (c)))
;
if (*s >= end)
}
else if (c == '/' && **s == '*')
{
- /* C-style comment. */
- ++*s;
- while (**s && (**s != '*' || *(*s + 1) != '/'))
- ++*s;
- if (**s)
- {
- *s += 2;
- goto loop;
- }
+ /* C-style comment. */
+ ++*s;
+ while (**s && (**s != '*' || *(*s + 1) != '/'))
+ ++*s;
+ if (**s)
+ {
+ *s += 2;
+ goto loop;
+ }
+ }
+
+ return c;
+}
+
+
+/* XBM bits seem to be backward within bytes compared with how
+ Windows does things. */
+static unsigned char reflect_byte (unsigned char orig)
+{
+ int i;
+ unsigned char reflected = 0x00;
+ for (i = 0; i < 8; i++)
+ {
+ if (orig & (0x01 << i))
+ reflected |= 0x80 >> i;
+ }
+ return reflected;
+}
+
+
+/* Create a Windows bitmap from X bitmap data. */
+static HBITMAP
+w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
+{
+ int i, j, w1, w2;
+ char *bits, *p;
+ HBITMAP bmp;
+
+ w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
+ w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
+ bits = (char *) xmalloc (height * w2);
+ bzero (bits, height * w2);
+ for (i = 0; i < height; i++)
+ {
+ p = bits + i*w2;
+ for (j = 0; j < w1; j++)
+ *p++ = reflect_byte(*data++);
}
+ bmp = CreateBitmap (width, height, 1, 1, bits);
+ xfree (bits);
- return c;
+ return bmp;
}
int LA1;
#define match() \
- LA1 = xbm_scan (contents, end, buffer, &value)
+ LA1 = xbm_scan (&s, end, buffer, &value)
#define expect(TOKEN) \
if (LA1 != (TOKEN)) \
if (v10)
{
-
for (i = 0; i < nbytes; i += 2)
{
int val = value;
expect (XBM_TK_NUMBER);
*p++ = val;
-
+
if (LA1 == ',' || LA1 == '}')
match ();
else
rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data);
if (rc)
{
- int depth = one_w32_display_info.n_cbits;
unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
unsigned long background = FRAME_BACKGROUND_PIXEL (f);
Lisp_Object value;
value = image_spec_value (img->spec, QCforeground, NULL);
if (!NILP (value))
foreground = x_alloc_image_color (f, img, value, foreground);
-
value = image_spec_value (img->spec, QCbackground, NULL);
if (!NILP (value))
- background = x_alloc_image_color (f, img, value, background);
-
-#if 0 /* TODO : Port image display to W32 */
+ {
+ background = x_alloc_image_color (f, img, value, background);
+ img->background = background;
+ img->background_valid = 1;
+ }
img->pixmap
- = XCreatePixmapFromBitmapData (FRAME_W32_DISPLAY (f),
- FRAME_W32_WINDOW (f),
- data,
- img->width, img->height,
- foreground, background,
- depth);
+ = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
+
xfree (data);
if (img->pixmap == 0)
}
else
success_p = 1;
-#endif
}
else
image_error ("Error loading XBM image `%s'", img->spec, Qnil);
data = image_spec_value (img->spec, QCdata, NULL);
in_memory_file_p = xbm_file_p (data);
- /* Parse the list specification. */
+ /* Parse the image specification. */
bcopy (xbm_format, fmt, sizeof fmt);
parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
xassert (parsed_p);
img->height = XFASTINT (fmt[XBM_HEIGHT].value);
xassert (img->width > 0 && img->height > 0);
}
+
/* Get foreground and background colors, maybe allocate colors. */
if (fmt[XBM_FOREGROUND].count
&& STRINGP (fmt[XBM_FOREGROUND].value))
bits = XSTRING (data)->data;
else
bits = XBOOL_VECTOR (data)->data;
-#ifdef TODO /* image support. */
+
/* Create the pixmap. */
- depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
+ depth = one_w32_display_info.n_cbits;
img->pixmap
- = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
- FRAME_X_WINDOW (f),
- bits,
- img->width, img->height,
- foreground, background,
- depth);
-#endif
+ = w32_create_pixmap_from_bitmap_data (img->width, img->height,
+ bits);
+
if (img->pixmap)
success_p = 1;
else
XPM_RELIEF,
XPM_ALGORITHM,
XPM_HEURISTIC_MASK,
+ XPM_MASK,
XPM_COLOR_SYMBOLS,
+ XPM_BACKGROUND,
XPM_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type XBM. */
/***********************************************************************
Algorithms
***********************************************************************/
-#if 0 /* TODO: image support. */
static XColor *x_to_xcolors P_ ((struct frame *, struct image *, int));
static void x_from_xcolors P_ ((struct frame *, struct image *, XColor *));
static void x_detect_edges P_ ((struct frame *, struct image *, int[9], int));
+static void XPutPixel (XImage *, int, int, COLORREF);
/* Non-zero means draw a cross on images having `:conversion
disabled'. */
XImage *ximg;
colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors);
-
+#if 0 /* TODO: implement image colors. */
/* Get the X image IMG->pixmap. */
ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
0, 0, img->width, img->height, ~0, ZPixmap);
}
XDestroyImage (ximg);
+#endif
return colors;
}
+/* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
+ created with CreateDIBSection, with the pointer to the bit values
+ stored in ximg->data. */
+
+static void XPutPixel (ximg, x, y, color)
+ XImage * ximg;
+ int x, y;
+ COLORREF color;
+{
+ int width = ximg->info.bmiHeader.biWidth;
+ int height = ximg->info.bmiHeader.biHeight;
+ int rowbytes = width * 3;
+ unsigned char * pixel;
+
+ /* Don't support putting pixels in images with palettes. */
+ xassert (ximg->info.bmiHeader.biBitCount == 24);
+
+ /* Ensure scanlines are aligned on 4 byte boundaries. */
+ if (rowbytes % 4)
+ rowbytes += 4 - (rowbytes % 4);
+
+ pixel = ximg->data + y * rowbytes + x * 3;
+ *pixel = 255 - GetRValue (color);
+ *(pixel + 1) = 255 - GetGValue (color);
+ *(pixel + 2) = 255 - GetBValue (color);
+}
+
/* Create IMG->pixmap from an array COLORS of XColor structures, whose
RGB members are set. F is the frame on which this all happens.
XImage *oimg;
Pixmap pixmap;
XColor *p;
-
+#if 0 /* TODO: color tables. */
init_color_table ();
-
+#endif
x_create_x_image_and_pixmap (f, img->width, img->height, 0,
&oimg, &pixmap);
p = colors;
for (x = 0; x < img->width; ++x, ++p)
{
unsigned long pixel;
+#if 0 /* TODO: color tables. */
pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
+#else
+ pixel = PALETTERGB (p->red, p->green, p->blue);
+#endif
XPutPixel (oimg, x, y, pixel);
}
x_put_x_image (f, oimg, pixmap, img->width, img->height);
x_destroy_x_image (oimg);
img->pixmap = pixmap;
+#if 0 /* TODO: color tables. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
}
struct frame *f;
struct image *img;
{
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
- if (dpyinfo->n_planes >= 2)
+ if (dpyinfo->n_planes * dpyinfo->n_cbits >= 2)
{
/* Color (or grayscale). Convert to gray, and equalize. Just
drawing such images with a stipple can look very odd, so
/* Draw a cross over the disabled image, if we must or if we
should. */
- if (dpyinfo->n_planes < 2 || cross_disabled_images)
+ if (dpyinfo->n_planes * dpyinfo->n_cbits < 2 || cross_disabled_images)
{
+#if 0 /* TODO: full image support */
Display *dpy = FRAME_X_DISPLAY (f);
GC gc;
img->width - 1, 0);
XFreeGC (dpy, gc);
}
+#endif
}
}
struct image *img;
Lisp_Object how;
{
+#if 0 /* TODO: full image support. */
Display *dpy = FRAME_W32_DISPLAY (f);
XImage *ximg, *mask_img;
- int x, y, rc, look_at_corners_p;
- unsigned long bg;
+ int x, y, rc, use_img_background;
+ unsigned long bg = 0;
+
+ if (img->mask)
+ {
+ XFreePixmap (FRAME_X_DISPLAY (f), img->mask);
+ img->mask = None;
+ img->background_transparent_valid = 0;
+ }
- BLOCK_INPUT;
-
/* Create an image and pixmap serving as mask. */
rc = x_create_x_image_and_pixmap (f, img->width, img->height, 1,
&mask_img, &img->mask);
if (!rc)
- {
- UNBLOCK_INPUT;
- return 0;
- }
+ return 0;
/* Get the X image of IMG->pixmap. */
ximg = XGetImage (dpy, img->pixmap, 0, 0, img->width, img->height,
~0, ZPixmap);
/* Determine the background color of ximg. If HOW is `(R G B)'
- take that as color. Otherwise, try to determine the color
- heuristically. */
- look_at_corners_p = 1;
+ take that as color. Otherwise, use the image's background color. */
+ use_img_background = 1;
if (CONSP (how))
{
- int rgb[3], i = 0;
+ int rgb[3], i;
- while (i < 3
- && CONSP (how)
- && NATNUMP (XCAR (how)))
+ for (i = 0; i < 3 && CONSP (how) && NATNUMP (XCAR (how)); ++i)
{
rgb[i] = XFASTINT (XCAR (how)) & 0xffff;
how = XCDR (how);
if (i == 3 && NILP (how))
{
char color_name[30];
- XColor exact, color;
- Colormap cmap;
-
sprintf (color_name, "#%04x%04x%04x", rgb[0], rgb[1], rgb[2]);
-
- cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
- if (XLookupColor (dpy, cmap, color_name, &exact, &color))
- {
- bg = color.pixel;
- look_at_corners_p = 0;
- }
+ bg = x_alloc_image_color (f, img, build_string (color_name), 0);
+ use_img_background = 0;
}
}
- if (look_at_corners_p)
- {
- unsigned long corners[4];
- int i, best_count;
-
- /* Get the colors at the corners of ximg. */
- corners[0] = XGetPixel (ximg, 0, 0);
- corners[1] = XGetPixel (ximg, img->width - 1, 0);
- corners[2] = XGetPixel (ximg, img->width - 1, img->height - 1);
- corners[3] = XGetPixel (ximg, 0, img->height - 1);
-
- /* Choose the most frequently found color as background. */
- for (i = best_count = 0; i < 4; ++i)
- {
- int j, n;
-
- for (j = n = 0; j < 4; ++j)
- if (corners[i] == corners[j])
- ++n;
-
- if (n > best_count)
- bg = corners[i], best_count = n;
- }
- }
+ if (use_img_background)
+ bg = four_corners_best (ximg, img->width, img->height);
/* Set all bits in mask_img to 1 whose color in ximg is different
from the background color bg. */
for (x = 0; x < img->width; ++x)
XPutPixel (mask_img, x, y, XGetPixel (ximg, x, y) != bg);
+ /* Fill in the background_transparent field while we have the mask handy. */
+ image_background_transparent (img, f, mask_img);
+
/* Put mask_img into img->mask. */
x_put_x_image (f, mask_img, img->mask, img->width, img->height);
x_destroy_x_image (mask_img);
XDestroyImage (ximg);
-
- UNBLOCK_INPUT;
return 1;
+#else
+ return 0;
+#endif
}
-#endif /* TODO */
\f
/***********************************************************************
PBM (mono, gray, color)
***********************************************************************/
-#ifdef HAVE_PBM
static int pbm_image_p P_ ((Lisp_Object object));
static int pbm_load P_ ((struct frame *f, struct image *img));
PBM_RELIEF,
PBM_ALGORITHM,
PBM_HEURISTIC_MASK,
+ PBM_MASK,
+ PBM_FOREGROUND,
+ PBM_BACKGROUND,
PBM_LAST
};
|| (type != PBM_MONO && max_color_idx < 0))
goto error;
- 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))
goto error;
+#if 0 /* TODO: color tables. */
/* Initialize the color hash table. */
init_color_table ();
+#endif
if (type == PBM_MONO)
{
fg = x_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
if (fmt[PBM_BACKGROUND].count
&& STRINGP (fmt[PBM_BACKGROUND].value))
- bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
-
+ {
+ bg = x_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
+ img->background = bg;
+ img->background_valid = 1;
+ }
+
for (y = 0; y < height; ++y)
for (x = 0; x < width; ++x)
{
if (r < 0 || g < 0 || b < 0)
{
- xfree (ximg->data);
- ximg->data = NULL;
- XDestroyImage (ximg);
+ x_destroy_x_image (ximg);
image_error ("Invalid pixel value in image `%s'",
img->spec, Qnil);
goto error;
}
/* RGB values are now in the range 0..max_color_idx.
- Scale this to the range 0..0xffff supported by X. */
- r = (double) r * 65535 / max_color_idx;
- g = (double) g * 65535 / max_color_idx;
- b = (double) b * 65535 / max_color_idx;
- XPutPixel (ximg, x, y, lookup_rgb_color (f, r, g, b));
+ Scale this to the range 0..0xff supported by W32. */
+ r = (int) ((double) r * 255 / max_color_idx);
+ g = (int) ((double) g * 255 / max_color_idx);
+ b = (int) ((double) b * 255 / max_color_idx);
+ XPutPixel (ximg, x, y,
+#if 0 /* TODO: color tables. */
+ lookup_rgb_color (f, r, g, b));
+#else
+ PALETTERGB (r, g, b));
+#endif
}
}
-
+
+#if 0 /* TODO: color tables. */
/* Store in IMG->colors the colors allocated for the image, and
free the color table. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+#endif
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
/* Put the image into a pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
xfree (contents);
return 1;
}
-#endif /* HAVE_PBM */
\f
/***********************************************************************
PNG_RELIEF,
PNG_ALGORITHM,
PNG_HEURISTIC_MASK,
+ PNG_MASK,
+ PNG_BACKGROUND,
PNG_LAST
};
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `png'. */
struct gcpro gcpro1;
png_struct *png_ptr = NULL;
png_info *info_ptr = NULL, *end_info = NULL;
- FILE *fp = NULL;
+ FILE *volatile fp = NULL;
png_byte sig[8];
- png_byte *pixels = NULL;
- png_byte **rows = NULL;
+ png_byte *volatile pixels = NULL;
+ png_byte **volatile rows = NULL;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_byte channels;
if (!transparent_p)
{
png_color_16 *image_background;
+ Lisp_Object specified_bg
+ = image_spec_value (img->spec, QCbackground, NULL);
+
+
+ if (STRINGP (specified_bg))
+ /* The user specified `:background', use that. */
+ {
+ COLORREF color;
+ if (w32_defined_color (f, XSTRING (specified_bg)->data, &color, 0))
+ {
+ png_color_16 user_bg;
- if (png_get_bKGD (png_ptr, info_ptr, &image_background))
+ bzero (&user_bg, sizeof user_bg);
+ user_bg.red = color.red;
+ user_bg.green = color.green;
+ user_bg.blue = color.blue;
+
+ png_set_background (png_ptr, &user_bg,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+ }
+ }
+ else if (png_get_bKGD (png_ptr, info_ptr, &image_background))
/* Image contains a background color with which to
combine the image. */
png_set_background (png_ptr, image_background,
Colormap cmap;
png_color_16 frame_background;
- BLOCK_INPUT;
- cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
+ cmap = FRAME_X_COLORMAP (f);
color.pixel = FRAME_BACKGROUND_PIXEL (f);
- XQueryColor (FRAME_W32_DISPLAY (f), cmap, &color);
- UNBLOCK_INPUT;
+ x_query_color (f, &color);
bzero (&frame_background, sizeof frame_background);
frame_background.red = color.red;
fp = NULL;
}
- BLOCK_INPUT;
-
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
&img->pixmap))
- {
- UNBLOCK_INPUT;
- goto error;
- }
+ goto error;
/* Create an image and pixmap serving as mask if the PNG image
contains an alpha channel. */
x_destroy_x_image (ximg);
XFreePixmap (FRAME_W32_DISPLAY (f), img->pixmap);
img->pixmap = 0;
- UNBLOCK_INPUT;
goto error;
}
}
}
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ /* Set IMG's background color from the PNG image, unless the user
+ overrode it. */
+ {
+ png_color_16 *bg;
+ if (png_get_bKGD (png_ptr, info_ptr, &bg))
+ {
+ img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
+ img->background_valid = 1;
+ }
+ }
+
/* Remember colors allocated for this image. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
img->width = width;
img->height = height;
+ /* Maybe fill in the background field while we have ximg handy. */
+ IMAGE_BACKGROUND (img, f, ximg);
+
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
/* Same for the mask. */
if (mask_img)
{
+ /* Fill in the background_transparent field while we have the mask
+ handy. */
+ image_background_transparent (img, f, mask_img);
+
x_put_x_image (f, mask_img, img->mask, img->width, img->height);
x_destroy_x_image (mask_img);
}
- UNBLOCK_INPUT;
UNGCPRO;
return 1;
}
JPEG_RELIEF,
JPEG_ALGORITHM,
JPEG_HEURISTIC_MASK,
+ JPEG_MASK,
+ JPEG_BACKGROUND,
JPEG_LAST
};
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `jpeg'. */
struct my_jpeg_error_mgr mgr;
Lisp_Object file, specified_file;
Lisp_Object specified_data;
- FILE *fp = NULL;
+ FILE * volatile fp = NULL;
JSAMPARRAY buffer;
int row_stride, x, y;
XImage *ximg = NULL;
/* Customize libjpeg's error handling to call my_error_exit when an
error is detected. This function will perform a longjmp. */
- mgr.pub.error_exit = my_error_exit;
cinfo.err = jpeg_std_error (&mgr.pub);
+ mgr.pub.error_exit = my_error_exit;
if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
{
if (fp)
fclose (fp);
jpeg_destroy_decompress (&cinfo);
-
- BLOCK_INPUT;
/* If we already have an XImage, free that. */
x_destroy_x_image (ximg);
/* Free pixmap and colors. */
x_clear_image (f, img);
- UNBLOCK_INPUT;
UNGCPRO;
return 0;
}
width = img->width = cinfo.output_width;
height = img->height = cinfo.output_height;
- BLOCK_INPUT;
-
/* Create X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
&img->pixmap))
- {
- UNBLOCK_INPUT;
- longjmp (mgr.setjmp_buffer, 2);
- }
+ longjmp (mgr.setjmp_buffer, 2);
/* Allocate colors. When color quantization is used,
cinfo.actual_number_of_colors has been set with the number of
if (fp)
fclose (fp);
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
+
/* Put the image into the pixmap. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
TIFF_RELIEF,
TIFF_ALGORITHM,
TIFF_HEURISTIC_MASK,
+ TIFF_MASK,
+ TIFF_BACKGROUND,
TIFF_LAST
};
{":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
- {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `tiff'. */
img->colors = colors_in_color_table (&img->ncolors);
free_color_table ();
+ img->width = width;
+ img->height = height;
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
+
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
xfree (buf);
-
- img->width = width;
- img->height = height;
UNGCPRO;
return 1;
GIF_RELIEF,
GIF_ALGORITHM,
GIF_HEURISTIC_MASK,
+ GIF_MASK,
GIF_IMAGE,
+ GIF_BACKGROUND,
GIF_LAST
};
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
{":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":image", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `gif'. */
width = img->width = gif->SWidth;
height = img->height = gif->SHeight;
- BLOCK_INPUT;
-
/* Create the X image and pixmap. */
if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
{
- UNBLOCK_INPUT;
DGifCloseFile (gif);
UNGCPRO;
return 0;
{
static int interlace_start[] = {0, 4, 2, 1};
static int interlace_increment[] = {8, 8, 4, 2};
- int pass, inc;
+ int pass;
int row = interlace_start[0];
pass = 0;
}
DGifCloseFile (gif);
-
+
+ /* Maybe fill in the background field while we have ximg handy. */
+ if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
+ IMAGE_BACKGROUND (img, f, ximg);
+
/* Put the image into the pixmap, then free the X image and its buffer. */
x_put_x_image (f, ximg, img->pixmap, width, height);
x_destroy_x_image (ximg);
- UNBLOCK_INPUT;
UNGCPRO;
return 1;
GS_RELIEF,
GS_ALGORITHM,
GS_HEURISTIC_MASK,
+ GS_MASK,
+ GS_BACKGROUND,
GS_LAST
};
{":margin", IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR, 0},
{":relief", IMAGE_INTEGER_VALUE, 0},
{":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
- {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
+ {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
+ {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
};
/* Structure describing the image type `ghostscript'. */
xassert (img->pixmap == 0);
img->pixmap = XCreatePixmap (FRAME_W32_DISPLAY (f), FRAME_W32_WINDOW (f),
img->width, img->height,
- DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+ one_w32_display_info.n_cbits);
UNBLOCK_INPUT;
if (!img->pixmap)
DEFUN ("x-change-window-property", Fx_change_window_property,
Sx_change_window_property, 2, 3, 0,
- "Change window property PROP to VALUE on the X window of FRAME.\n\
-PROP and VALUE must be strings. FRAME nil or omitted means use the\n\
-selected frame. Value is VALUE.")
+ doc: /* Change window property PROP to VALUE on the X window of FRAME.
+PROP and VALUE must be strings. FRAME nil or omitted means use the
+selected frame. Value is VALUE. */)
(prop, value, frame)
Lisp_Object frame, prop, value;
{
DEFUN ("x-delete-window-property", Fx_delete_window_property,
Sx_delete_window_property, 1, 2, 0,
- "Remove window property PROP from X window of FRAME.\n\
-FRAME nil or omitted means use the selected frame. Value is PROP.")
+ doc: /* Remove window property PROP from X window of FRAME.
+FRAME nil or omitted means use the selected frame. Value is PROP. */)
(prop, frame)
Lisp_Object prop, frame;
{
DEFUN ("x-window-property", Fx_window_property, Sx_window_property,
1, 2, 0,
- "Value is the value of window property PROP on FRAME.\n\
-If FRAME is nil or omitted, use the selected frame. Value is nil\n\
-if FRAME hasn't a property with name PROP or if PROP has no string\n\
-value.")
+ doc: /* Value is the value of window property PROP on FRAME.
+If FRAME is nil or omitted, use the selected frame. Value is nil
+if FRAME hasn't a property with name PROP or if PROP has no string
+value. */)
(prop, frame)
Lisp_Object prop, frame;
{
struct w32_display_info *dpyinfo;
Lisp_Object parms, text;
{
-#if 0 /* TODO : w32 version */
struct frame *f;
Lisp_Object frame, tem;
Lisp_Object name;
Lisp_Object buffer;
struct buffer *old_buffer;
- check_x ();
+ check_w32 ();
/* Use this general default value to start with until we know if
this frame has a specified name. */
frame = Qnil;
GCPRO3 (parms, name, frame);
- f = make_frame (1);
+ /* Make a frame without minibuffer nor mode-line. */
+ f = make_frame (0);
+ f->wants_modeline = 0;
XSETFRAME (frame, f);
buffer = Fget_buffer_create (build_string (" *tip*"));
f->output_data.w32 =
(struct w32_output *) xmalloc (sizeof (struct w32_output));
bzero (f->output_data.w32, sizeof (struct w32_output));
-#if 0
- f->output_data.w32->icon_bitmap = -1;
-#endif
- f->output_data.w32->fontset = -1;
+
+ FRAME_FONTSET (f) = -1;
f->icon_name = Qnil;
-#ifdef GLYPH_DEBUG
+#if 0 /* GLYPH_DEBUG TODO: image support. */
image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
be set. */
if (EQ (name, Qunbound) || NILP (name))
{
- f->name = build_string (dpyinfo->x_id_name);
+ f->name = build_string (dpyinfo->w32_id_name);
f->explicit_name = 0;
}
else
/* Try out a font which we hope has bold and italic variations. */
if (!STRINGP (font))
- font = x_new_font (f, "-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1");
- if (!STRINGP (font))
- font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
- if (! STRINGP (font))
- font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_font (f, "-*-Courier New-normal-r-*-*-*-100-*-*-c-*-iso8859-1");
if (! STRINGP (font))
- /* This was formerly the first thing tried, but it finds too many fonts
- and takes too long. */
- font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1");
+ font = x_new_font (f, "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1");
/* If those didn't work, look for something which will at least work. */
if (! STRINGP (font))
- font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1");
+ font = x_new_font (f, "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1");
UNBLOCK_INPUT;
if (! STRINGP (font))
- font = build_string ("fixed");
+ font = build_string ("Fixedsys");
x_default_parameter (f, parms, Qfont, font,
"font", "Font", RES_TYPE_STRING);
x_default_parameter (f, parms, Qborder_width, make_number (2),
"borderWidth", "BorderWidth", RES_TYPE_NUMBER);
-
/* This defaults to 2 in order to match xterm. We recognize either
internalBorderWidth or internalBorder (which is what xterm calls
it). */
parms = Fcons (Fcons (Qinternal_border_width, value),
parms);
}
-
x_default_parameter (f, parms, Qinternal_border_width, make_number (1),
"internalBorderWidth", "internalBorderWidth",
RES_TYPE_NUMBER);
end up in init_iterator with a null face cache, which should not
happen. */
init_frame_faces (f);
-
+
+ f->output_data.w32->dwStyle = WS_BORDER | WS_POPUP | WS_DISABLED;
f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
+
window_prompting = x_figure_window_size (f, parms);
+ /* No fringes on tip frame. */
+ f->output_data.w32->fringes_extra = 0;
+ f->output_data.w32->fringe_cols = 0;
+ f->output_data.w32->left_fringe_width = 0;
+ f->output_data.w32->right_fringe_width = 0;
+
if (window_prompting & XNegative)
{
if (window_prompting & YNegative)
}
f->output_data.w32->size_hint_flags = window_prompting;
- {
- XSetWindowAttributes attrs;
- unsigned long mask;
-
- BLOCK_INPUT;
- mask = CWBackPixel | CWOverrideRedirect | CWEventMask;
- if (DoesSaveUnders (dpyinfo->screen))
- mask |= CWSaveUnder;
-
- /* Window managers looks at the override-redirect flag to
- determine whether or net to give windows a decoration (Xlib
- 3.2.8). */
- attrs.override_redirect = True;
- attrs.save_under = True;
- attrs.background_pixel = FRAME_BACKGROUND_PIXEL (f);
- /* Arrange for getting MapNotify and UnmapNotify events. */
- attrs.event_mask = StructureNotifyMask;
- tip_window
- = FRAME_W32_WINDOW (f)
- = XCreateWindow (FRAME_W32_DISPLAY (f),
- FRAME_W32_DISPLAY_INFO (f)->root_window,
- /* x, y, width, height */
- 0, 0, 1, 1,
- /* Border. */
- 1,
- CopyFromParent, InputOutput, CopyFromParent,
- mask, &attrs);
- UNBLOCK_INPUT;
- }
+
+ BLOCK_INPUT;
+ my_create_tip_window (f);
+ UNBLOCK_INPUT;
x_make_gc (f);
/* Discard the unwind_protect. */
return unbind_to (count, frame);
-#endif /* TODO */
- return Qnil;
}
int width, height;
int *root_x, *root_y;
{
-#ifdef TODO /* Tool tips not supported. */
Lisp_Object left, top;
- int win_x, win_y;
- Window root, child;
- unsigned pmask;
/* User-specified position? */
left = Fcdr (Fassq (Qleft, parms));
/* Move the tooltip window where the mouse pointer is. Resize and
show it. */
- if (!INTEGERP (left) && !INTEGERP (top))
+ if (!INTEGERP (left) || !INTEGERP (top))
{
+ POINT pt;
+
BLOCK_INPUT;
- XQueryPointer (FRAME_X_DISPLAY (f), FRAME_X_DISPLAY_INFO (f)->root_window,
- &root, &child, root_x, root_y, &win_x, &win_y, &pmask);
+ GetCursorPos (&pt);
+ *root_x = pt.x;
+ *root_y = pt.y;
UNBLOCK_INPUT;
}
if (INTEGERP (left))
*root_x = XINT (left);
- else if (*root_x + XINT (dx) + width > FRAME_X_DISPLAY_INFO (f)->width)
+ else if (*root_x + XINT (dx) + width <= FRAME_W32_DISPLAY_INFO (f)->width)
+ /* It fits to the right of the pointer. */
+ *root_x += XINT (dx);
+ else if (width + XINT (dx) <= *root_x)
+ /* It fits to the left of the pointer. */
*root_x -= width + XINT (dx);
else
- *root_x += XINT (dx);
-
-#endif /* Tooltip support. */
+ /* Put it left justified on the screen -- it ought to fit that way. */
+ *root_x = 0;
}
-#ifdef TODO /* Tooltip support not complete. */
DEFUN ("x-show-tip", Fx_show_tip, Sx_show_tip, 1, 6, 0,
- "Show STRING in a \"tooltip\" window on frame FRAME.\n\
-A tooltip window is a small window displaying a string.\n\
-\n\
-FRAME nil or omitted means use the selected frame.\n\
-\n\
-PARMS is an optional list of frame parameters which can be\n\
-used to change the tooltip's appearance.\n\
-\n\
-Automatically hide the tooltip after TIMEOUT seconds.\n\
-TIMEOUT nil means use the default timeout of 5 seconds.\n\
-\n\
-If the list of frame parameters PARAMS contains a `left' parameters,\n\
-the tooltip is displayed at that x-position. Otherwise it is\n\
-displayed at the mouse position, with offset DX added (default is 5 if\n\
-DX isn't specified). Likewise for the y-position; if a `top' frame\n\
-parameter is specified, it determines the y-position of the tooltip\n\
-window, otherwise it is displayed at the mouse position, with offset\n\
-DY added (default is -10).\n\
-\n\
-A tooltip's maximum size is specified by `x-max-tooltip-size'.\n\
-Text larger than the specified size is clipped.")
+ doc: /* Show STRING in a \"tooltip\" window on frame FRAME.
+A tooltip window is a small window displaying a string.
+
+FRAME nil or omitted means use the selected frame.
+
+PARMS is an optional list of frame parameters which can be
+used to change the tooltip's appearance.
+
+Automatically hide the tooltip after TIMEOUT seconds. TIMEOUT nil
+means use the default timeout of 5 seconds.
+
+If the list of frame parameters PARAMS contains a `left' parameter,
+the tooltip is displayed at that x-position. Otherwise it is
+displayed at the mouse position, with offset DX added (default is 5 if
+DX isn't specified). Likewise for the y-position; if a `top' frame
+parameter is specified, it determines the y-position of the tooltip
+window, otherwise it is displayed at the mouse position, with offset
+DY added (default is -10).
+
+A tooltip's maximum size is specified by `x-max-tooltip-size'.
+Text larger than the specified size is clipped. */)
(string, frame, parms, timeout, dx, dy)
Lisp_Object string, frame, parms, timeout, dx, dy;
{
struct frame *f;
struct window *w;
- Lisp_Object buffer, top, left, max_width, max_height;
int root_x, root_y;
struct buffer *old_buffer;
struct text_pos pos;
int i, width, height;
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
int old_windows_or_buffers_changed = windows_or_buffers_changed;
- int count = specpdl_ptr - specpdl;
+ int count = BINDING_STACK_SIZE ();
specbind (Qinhibit_redisplay, Qt);
}
BLOCK_INPUT;
- compute_tip_xy (f, parms, dx, dy, &root_x, &root_y);
- XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- root_x, root_y - PIXEL_HEIGHT (f));
+ compute_tip_xy (f, parms, dx, dy, PIXEL_WIDTH (f),
+ PIXEL_HEIGHT (f), &root_x, &root_y);
+
+ /* Put tooltip in topmost group and in position. */
+ SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
+ root_x, root_y, 0, 0,
+ SWP_NOSIZE | SWP_NOACTIVATE);
+
+ /* Ensure tooltip is on top of other topmost windows (eg menus). */
+ SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
+ 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
UNBLOCK_INPUT;
goto start_timer;
}
parms = Fcons (Fcons (Qbackground_color, build_string ("lightyellow")),
parms);
+ /* Block input until the tip has been fully drawn, to avoid crashes
+ when drawing tips in menus. */
+ BLOCK_INPUT;
+
/* Create a frame for the tooltip, and record it in the global
variable tip_frame. */
- frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms);
+ frame = x_create_tip_frame (FRAME_W32_DISPLAY_INFO (f), parms, string);
f = XFRAME (frame);
/* Set up the frame's root window. */
/* Let the row go over the full width of the frame. */
row->full_width_p = 1;
+#ifdef TODO /* Investigate why some fonts need more width than is
+ calculated for some tooltips. */
/* There's a glyph at the end of rows that is use to place
the cursor there. Don't include the width of this glyph. */
if (row->used[TEXT_AREA])
row_width = row->pixel_width - last->pixel_width;
}
else
+#endif
row_width = row->pixel_width;
+ /* TODO: find why tips do not draw along baseline as instructed. */
height += row->height;
width = max (width, row_width);
}
show it. */
compute_tip_xy (f, parms, dx, dy, width, height, &root_x, &root_y);
- BLOCK_INPUT;
- XMoveResizeWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- root_x, root_y - height, width, height);
- XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
- UNBLOCK_INPUT;
+ {
+ /* Adjust Window size to take border into account. */
+ RECT rect;
+ rect.left = rect.top = 0;
+ rect.right = width;
+ rect.bottom = height;
+ AdjustWindowRect (&rect, f->output_data.w32->dwStyle,
+ FRAME_EXTERNAL_MENU_BAR (f));
+
+ /* Position and size tooltip, and put it in the topmost group. */
+ SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOPMOST,
+ root_x, root_y, rect.right - rect.left,
+ rect.bottom - rect.top, SWP_NOACTIVATE);
+
+ /* Ensure tooltip is on top of other topmost windows (eg menus). */
+ SetWindowPos (FRAME_W32_WINDOW (f), HWND_TOP,
+ 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ /* Let redisplay know that we have made the frame visible already. */
+ f->async_visible = 1;
+
+ ShowWindow (FRAME_W32_WINDOW (f), SW_SHOWNOACTIVATE);
+ }
/* Draw into the window. */
w->must_be_updated_p = 1;
update_single_window (w, 1);
+ UNBLOCK_INPUT;
+
/* Restore original current buffer. */
set_buffer_internal_1 (old_buffer);
windows_or_buffers_changed = old_windows_or_buffers_changed;
DEFUN ("x-hide-tip", Fx_hide_tip, Sx_hide_tip, 0, 0, 0,
- "Hide the current tooltip window, if there is any.\n\
-Value is t if tooltip was open, nil otherwise.")
+ doc: /* Hide the current tooltip window, if there is any.
+Value is t if tooltip was open, nil otherwise. */)
()
{
int count;
UNGCPRO;
return unbind_to (count, deleted);
}
-#endif
\f
extern Lisp_Object Qfile_name_history;
DEFUN ("x-file-dialog", Fx_file_dialog, Sx_file_dialog, 2, 4, 0,
- "Read file name, prompting with PROMPT in directory DIR.\n\
-Use a file selection dialog.\n\
-Select DEFAULT-FILENAME in the dialog's file selection box, if\n\
-specified. Ensure that file exists if MUSTMATCH is non-nil.")
+ doc: /* Read file name, prompting with PROMPT in directory DIR.
+Use a file selection dialog.
+Select DEFAULT-FILENAME in the dialog's file selection box, if
+specified. Ensure that file exists if MUSTMATCH is non-nil. */)
(prompt, dir, default_filename, mustmatch)
Lisp_Object prompt, dir, default_filename, mustmatch;
{
if (GetOpenFileName (&file_details))
{
dostounix_filename (filename);
- file = build_string (filename);
+ file = DECODE_FILE(build_string (filename));
}
else
file = Qnil;
\f
-/***********************************************************************
- Tests
- ***********************************************************************/
-
-#if GLYPH_DEBUG
-
-DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
- "Value is non-nil if SPEC is a valid image specification.")
- (spec)
- Lisp_Object spec;
-{
- return valid_image_p (spec) ? Qt : Qnil;
-}
-
-
-DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
- (spec)
- Lisp_Object spec;
-{
- int id = -1;
-
- if (valid_image_p (spec))
- id = lookup_image (SELECTED_FRAME (), spec);
-
- debug_print (spec);
- return make_number (id);
-}
-
-#endif /* GLYPH_DEBUG != 0 */
-
-
-\f
/***********************************************************************
w32 specialized functions
***********************************************************************/
-DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 1, 0,
- "This will display the W32 font dialog and return an X font string corresponding to the selection.")
- (frame)
- Lisp_Object frame;
+DEFUN ("w32-select-font", Fw32_select_font, Sw32_select_font, 0, 2, 0,
+ doc: /* Select a font using the W32 font dialog.
+Returns an X font string corresponding to the selection. */)
+ (frame, include_proportional)
+ Lisp_Object frame, include_proportional;
{
FRAME_PTR f = check_x_frame (frame);
CHOOSEFONT cf;
cf.lStructSize = sizeof (cf);
cf.hwndOwner = FRAME_W32_WINDOW (f);
- cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS;
+ cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS;
+
+ /* Unless include_proportional is non-nil, limit the selection to
+ monospaced fonts. */
+ if (NILP (include_proportional))
+ cf.Flags |= CF_FIXEDPITCHONLY;
+
cf.lpLogFont = &lf;
/* Initialize as much of the font details as we can from the current
return build_string (buf);
}
-DEFUN ("w32-send-sys-command", Fw32_send_sys_command, Sw32_send_sys_command, 1, 2, 0,
- "Send frame a Windows WM_SYSCOMMAND message of type COMMAND.\n\
-Some useful values for command are 0xf030 to maximise frame (0xf020\n\
-to minimize), 0xf120 to restore frame to original size, and 0xf100\n\
-to activate the menubar for keyboard access. 0xf140 activates the\n\
-screen saver if defined.\n\
-\n\
-If optional parameter FRAME is not specified, use selected frame.")
+DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
+ Sw32_send_sys_command, 1, 2, 0,
+ doc: /* Send frame a Windows WM_SYSCOMMAND message of type COMMAND.
+Some useful values for command are #xf030 to maximise frame (#xf020
+to minimize), #xf120 to restore frame to original size, and #xf100
+to activate the menubar for keyboard access. #xf140 activates the
+screen saver if defined.
+
+If optional parameter FRAME is not specified, use selected frame. */)
(command, frame)
Lisp_Object command, frame;
{
}
DEFUN ("w32-shell-execute", Fw32_shell_execute, Sw32_shell_execute, 2, 4, 0,
- "Get Windows to perform OPERATION on DOCUMENT.\n\
-This is a wrapper around the ShellExecute system function, which\n\
-invokes the application registered to handle OPERATION for DOCUMENT.\n\
-OPERATION is typically \"open\", \"print\" or \"explore\" (but can be\n\
-nil for the default action), and DOCUMENT is typically the name of a\n\
-document file or URL, but can also be a program executable to run or\n\
-a directory to open in the Windows Explorer.\n\
-\n\
-If DOCUMENT is a program executable, PARAMETERS can be a string\n\
-containing command line parameters, but otherwise should be nil.\n\
-\n\
-SHOW-FLAG can be used to control whether the invoked application is hidden\n\
-or minimized. If SHOW-FLAG is nil, the application is displayed normally,\n\
-otherwise it is an integer representing a ShowWindow flag:\n\
-\n\
- 0 - start hidden\n\
- 1 - start normally\n\
- 3 - start maximized\n\
- 6 - start minimized")
+ doc: /* Get Windows to perform OPERATION on DOCUMENT.
+This is a wrapper around the ShellExecute system function, which
+invokes the application registered to handle OPERATION for DOCUMENT.
+OPERATION is typically \"open\", \"print\" or \"explore\" (but can be
+nil for the default action), and DOCUMENT is typically the name of a
+document file or URL, but can also be a program executable to run or
+a directory to open in the Windows Explorer.
+
+If DOCUMENT is a program executable, PARAMETERS can be a string
+containing command line parameters, but otherwise should be nil.
+
+SHOW-FLAG can be used to control whether the invoked application is hidden
+or minimized. If SHOW-FLAG is nil, the application is displayed normally,
+otherwise it is an integer representing a ShowWindow flag:
+
+ 0 - start hidden
+ 1 - start normally
+ 3 - start maximized
+ 6 - start minimized */)
(operation, document, parameters, show_flag)
Lisp_Object operation, document, parameters, show_flag;
{
c = Fcar (c);
if (!SYMBOLP (c))
abort ();
- vk_code = lookup_vk_code (XSYMBOL (c)->name->data);
+ vk_code = lookup_vk_code (XSTRING (SYMBOL_NAME (c))->data);
}
else if (INTEGERP (c))
{
return HOTKEY (vk_code, w32_modifiers);
}
-DEFUN ("w32-register-hot-key", Fw32_register_hot_key, Sw32_register_hot_key, 1, 1, 0,
- "Register KEY as a hot-key combination.\n\
-Certain key combinations like Alt-Tab are reserved for system use on\n\
-Windows, and therefore are normally intercepted by the system. However,\n\
-most of these key combinations can be received by registering them as\n\
-hot-keys, overriding their special meaning.\n\
-\n\
-KEY must be a one element key definition in vector form that would be\n\
-acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta\n\
-modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper\n\
-is always interpreted as the Windows modifier keys.\n\
-\n\
-The return value is the hotkey-id if registered, otherwise nil.")
+DEFUN ("w32-register-hot-key", Fw32_register_hot_key,
+ Sw32_register_hot_key, 1, 1, 0,
+ doc: /* Register KEY as a hot-key combination.
+Certain key combinations like Alt-Tab are reserved for system use on
+Windows, and therefore are normally intercepted by the system. However,
+most of these key combinations can be received by registering them as
+hot-keys, overriding their special meaning.
+
+KEY must be a one element key definition in vector form that would be
+acceptable to `define-key' (e.g. [A-tab] for Alt-Tab). The meta
+modifier is interpreted as Alt if `w32-alt-is-meta' is t, and hyper
+is always interpreted as the Windows modifier keys.
+
+The return value is the hotkey-id if registered, otherwise nil. */)
(key)
Lisp_Object key;
{
return key;
}
-DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, Sw32_unregister_hot_key, 1, 1, 0,
- "Unregister HOTKEY as a hot-key combination.")
+DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key,
+ Sw32_unregister_hot_key, 1, 1, 0,
+ doc: /* Unregister HOTKEY as a hot-key combination. */)
(key)
Lisp_Object key;
{
return Qnil;
}
-DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys, Sw32_registered_hot_keys, 0, 0, 0,
- "Return list of registered hot-key IDs.")
+DEFUN ("w32-registered-hot-keys", Fw32_registered_hot_keys,
+ Sw32_registered_hot_keys, 0, 0, 0,
+ doc: /* Return list of registered hot-key IDs. */)
()
{
return Fcopy_sequence (w32_grabbed_keys);
}
-DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key, Sw32_reconstruct_hot_key, 1, 1, 0,
- "Convert hot-key ID to a lisp key combination.")
+DEFUN ("w32-reconstruct-hot-key", Fw32_reconstruct_hot_key,
+ Sw32_reconstruct_hot_key, 1, 1, 0,
+ doc: /* Convert hot-key ID to a lisp key combination. */)
(hotkeyid)
Lisp_Object hotkeyid;
{
return key;
}
-DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key, Sw32_toggle_lock_key, 1, 2, 0,
- "Toggle the state of the lock key KEY.\n\
-KEY can be `capslock', `kp-numlock', or `scroll'.\n\
-If the optional parameter NEW-STATE is a number, then the state of KEY\n\
-is set to off if the low bit of NEW-STATE is zero, otherwise on.")
+DEFUN ("w32-toggle-lock-key", Fw32_toggle_lock_key,
+ Sw32_toggle_lock_key, 1, 2, 0,
+ doc: /* Toggle the state of the lock key KEY.
+KEY can be `capslock', `kp-numlock', or `scroll'.
+If the optional parameter NEW-STATE is a number, then the state of KEY
+is set to off if the low bit of NEW-STATE is zero, otherwise on. */)
(key, new_state)
Lisp_Object key, new_state;
{
}
\f
DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
- "Return storage information about the file system FILENAME is on.\n\
-Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total\n\
-storage of the file system, FREE is the free storage, and AVAIL is the\n\
-storage available to a non-superuser. All 3 numbers are in bytes.\n\
-If the underlying system call fails, value is nil.")
+ doc: /* Return storage information about the file system FILENAME is on.
+Value is a list of floats (TOTAL FREE AVAIL), where TOTAL is the total
+storage of the file system, FREE is the free storage, and AVAIL is the
+storage available to a non-superuser. All 3 numbers are in bytes.
+If the underlying system call fails, value is nil. */)
(filename)
Lisp_Object filename;
{
if (pfn_GetDiskFreeSpaceEx)
{
+ /* Unsigned large integers cannot be cast to double, so
+ use signed ones instead. */
LARGE_INTEGER availbytes;
LARGE_INTEGER freebytes;
LARGE_INTEGER totalbytes;
if (pfn_GetDiskFreeSpaceEx(rootname,
- &availbytes,
- &totalbytes,
- &freebytes))
+ (ULARGE_INTEGER *)&availbytes,
+ (ULARGE_INTEGER *)&totalbytes,
+ (ULARGE_INTEGER *)&freebytes))
value = list3 (make_float ((double) totalbytes.QuadPart),
make_float ((double) freebytes.QuadPart),
make_float ((double) availbytes.QuadPart));
return value;
}
\f
+/***********************************************************************
+ Initialization
+ ***********************************************************************/
+
+void
syms_of_w32fns ()
{
+ HMODULE user32_lib = GetModuleHandle ("user32.dll");
+
/* This is zero if not using MS-Windows. */
w32_in_use = 0;
- /* The section below is built by the lisp expression at the top of the file,
- just above where these variables are declared. */
- /*&&& init symbols here &&&*/
+ /* 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");
+ track_mouse_window = NULL;
+
+ w32_visible_system_caret_hwnd = NULL;
+
Qauto_raise = intern ("auto-raise");
staticpro (&Qauto_raise);
Qauto_lower = intern ("auto-lower");
staticpro (&Qcenter);
Qcancel_timer = intern ("cancel-timer");
staticpro (&Qcancel_timer);
- /* This is the end of symbol initialization. */
+ Qfullscreen = intern ("fullscreen");
+ staticpro (&Qfullscreen);
+ Qfullwidth = intern ("fullwidth");
+ staticpro (&Qfullwidth);
+ Qfullheight = intern ("fullheight");
+ staticpro (&Qfullheight);
+ Qfullboth = intern ("fullboth");
+ staticpro (&Qfullboth);
Qhyper = intern ("hyper");
staticpro (&Qhyper);
staticpro (&Qcontrol);
Qshift = intern ("shift");
staticpro (&Qshift);
+ /* This is the end of symbol initialization. */
/* Text property `display' should be nonsticky by default. */
Vtext_property_default_nonsticky
w32_grabbed_keys = Qnil;
DEFVAR_LISP ("w32-color-map", &Vw32_color_map,
- "An array of color name mappings for windows.");
+ doc: /* An array of color name mappings for windows. */);
Vw32_color_map = Qnil;
DEFVAR_LISP ("w32-pass-alt-to-system", &Vw32_pass_alt_to_system,
- "Non-nil if alt key presses are passed on to Windows.\n\
-When non-nil, for example, alt pressed and released and then space will\n\
-open the System menu. When nil, Emacs silently swallows alt key events.");
+ doc: /* Non-nil if alt key presses are passed on to Windows.
+When non-nil, for example, alt pressed and released and then space will
+open the System menu. When nil, Emacs silently swallows alt key events. */);
Vw32_pass_alt_to_system = Qnil;
DEFVAR_LISP ("w32-alt-is-meta", &Vw32_alt_is_meta,
- "Non-nil if the alt key is to be considered the same as the meta key.\n\
-When nil, Emacs will translate the alt key to the Alt modifier, and not Meta.");
+ doc: /* Non-nil if the alt key is to be considered the same as the meta key.
+When nil, Emacs will translate the alt key to the Alt modifier, and not Meta. */);
Vw32_alt_is_meta = Qt;
DEFVAR_INT ("w32-quit-key", &Vw32_quit_key,
- "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. */);
XSETINT (Vw32_quit_key, 0);
DEFVAR_LISP ("w32-pass-lwindow-to-system",
&Vw32_pass_lwindow_to_system,
- "Non-nil if the left \"Windows\" key is passed on to Windows.\n\
-When non-nil, the Start menu is opened by tapping the key.");
+ doc: /* Non-nil if the left \"Windows\" key is passed on to Windows.
+When non-nil, the Start menu is opened by tapping the key. */);
Vw32_pass_lwindow_to_system = Qt;
DEFVAR_LISP ("w32-pass-rwindow-to-system",
&Vw32_pass_rwindow_to_system,
- "Non-nil if the right \"Windows\" key is passed on to Windows.\n\
-When non-nil, the Start menu is opened by tapping the key.");
+ doc: /* Non-nil if the right \"Windows\" key is passed on to Windows.
+When non-nil, the Start menu is opened by tapping the key. */);
Vw32_pass_rwindow_to_system = Qt;
DEFVAR_INT ("w32-phantom-key-code",
&Vw32_phantom_key_code,
- "Virtual key code used to generate \"phantom\" key presses.\n\
-Value is a number between 0 and 255.\n\
-\n\
-Phantom key presses are generated in order to stop the system from\n\
-acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or\n\
-`w32-pass-rwindow-to-system' is nil.");
+ doc: /* Virtual key code used to generate \"phantom\" key presses.
+Value is a number between 0 and 255.
+
+Phantom key presses are generated in order to stop the system from
+acting on \"Windows\" key events when `w32-pass-lwindow-to-system' or
+`w32-pass-rwindow-to-system' is nil. */);
/* Although 255 is technically not a valid key code, it works and
means that this hack won't interfere with any real key code. */
Vw32_phantom_key_code = 255;
DEFVAR_LISP ("w32-enable-num-lock",
&Vw32_enable_num_lock,
- "Non-nil if Num Lock should act normally.\n\
-Set to nil to see Num Lock as the key `kp-numlock'.");
+ doc: /* Non-nil if Num Lock should act normally.
+Set to nil to see Num Lock as the key `kp-numlock'. */);
Vw32_enable_num_lock = Qt;
DEFVAR_LISP ("w32-enable-caps-lock",
&Vw32_enable_caps_lock,
- "Non-nil if Caps Lock should act normally.\n\
-Set to nil to see Caps Lock as the key `capslock'.");
+ doc: /* Non-nil if Caps Lock should act normally.
+Set to nil to see Caps Lock as the key `capslock'. */);
Vw32_enable_caps_lock = Qt;
DEFVAR_LISP ("w32-scroll-lock-modifier",
&Vw32_scroll_lock_modifier,
- "Modifier to use for the Scroll Lock on state.\n\
-The value can be hyper, super, meta, alt, control or shift for the\n\
-respective modifier, or nil to see Scroll Lock as the key `scroll'.\n\
-Any other value will cause the key to be ignored.");
+ doc: /* Modifier to use for the Scroll Lock on state.
+The value can be hyper, super, meta, alt, control or shift for the
+respective modifier, or nil to see Scroll Lock as the key `scroll'.
+Any other value will cause the key to be ignored. */);
Vw32_scroll_lock_modifier = Qt;
DEFVAR_LISP ("w32-lwindow-modifier",
&Vw32_lwindow_modifier,
- "Modifier to use for the left \"Windows\" key.\n\
-The value can be hyper, super, meta, alt, control or shift for the\n\
-respective modifier, or nil to appear as the key `lwindow'.\n\
-Any other value will cause the key to be ignored.");
+ doc: /* Modifier to use for the left \"Windows\" key.
+The value can be hyper, super, meta, alt, control or shift for the
+respective modifier, or nil to appear as the key `lwindow'.
+Any other value will cause the key to be ignored. */);
Vw32_lwindow_modifier = Qnil;
DEFVAR_LISP ("w32-rwindow-modifier",
&Vw32_rwindow_modifier,
- "Modifier to use for the right \"Windows\" key.\n\
-The value can be hyper, super, meta, alt, control or shift for the\n\
-respective modifier, or nil to appear as the key `rwindow'.\n\
-Any other value will cause the key to be ignored.");
+ doc: /* Modifier to use for the right \"Windows\" key.
+The value can be hyper, super, meta, alt, control or shift for the
+respective modifier, or nil to appear as the key `rwindow'.
+Any other value will cause the key to be ignored. */);
Vw32_rwindow_modifier = Qnil;
DEFVAR_LISP ("w32-apps-modifier",
&Vw32_apps_modifier,
- "Modifier to use for the \"Apps\" key.\n\
-The value can be hyper, super, meta, alt, control or shift for the\n\
-respective modifier, or nil to appear as the key `apps'.\n\
-Any other value will cause the key to be ignored.");
+ doc: /* Modifier to use for the \"Apps\" key.
+The value can be hyper, super, meta, alt, control or shift for the
+respective modifier, or nil to appear as the key `apps'.
+Any other value will cause the key to be ignored. */);
Vw32_apps_modifier = Qnil;
- DEFVAR_LISP ("w32-enable-synthesized-fonts", &Vw32_enable_synthesized_fonts,
- "Non-nil enables selection of artificially italicized and bold fonts.");
- Vw32_enable_synthesized_fonts = Qnil;
+ DEFVAR_BOOL ("w32-enable-synthesized-fonts", &w32_enable_synthesized_fonts,
+ doc: /* Non-nil enables selection of artificially italicized and bold fonts. */);
+ w32_enable_synthesized_fonts = 0;
DEFVAR_LISP ("w32-enable-palette", &Vw32_enable_palette,
- "Non-nil enables Windows palette management to map colors exactly.");
+ doc: /* Non-nil enables Windows palette management to map colors exactly. */);
Vw32_enable_palette = Qt;
DEFVAR_INT ("w32-mouse-button-tolerance",
&Vw32_mouse_button_tolerance,
- "Analogue of double click interval for faking middle mouse events.\n\
-The value is the minimum time in milliseconds that must elapse between\n\
-left/right button down events before they are considered distinct events.\n\
-If both mouse buttons are depressed within this interval, a middle mouse\n\
-button down event is generated instead.");
+ doc: /* Analogue of double click interval for faking middle mouse events.
+The value is the minimum time in milliseconds that must elapse between
+left/right button down events before they are considered distinct events.
+If both mouse buttons are depressed within this interval, a middle mouse
+button down event is generated instead. */);
XSETINT (Vw32_mouse_button_tolerance, GetDoubleClickTime () / 2);
DEFVAR_INT ("w32-mouse-move-interval",
&Vw32_mouse_move_interval,
- "Minimum interval between mouse move events.\n\
-The value is the minimum time in milliseconds that must elapse between\n\
-successive mouse move (or scroll bar drag) events before they are\n\
-reported as lisp events.");
+ doc: /* Minimum interval between mouse move events.
+The value is the minimum time in milliseconds that must elapse between
+successive mouse move (or scroll bar drag) events before they are
+reported as lisp events. */);
XSETINT (Vw32_mouse_move_interval, 0);
+ DEFVAR_BOOL ("w32-pass-extra-mouse-buttons-to-system",
+ &w32_pass_extra_mouse_buttons_to_system,
+ doc: /* Non-nil if the fourth and fifth mouse buttons are passed to Windows.
+Recent versions of Windows support mice with up to five buttons.
+Since most applications don't support these extra buttons, most mouse
+drivers will allow you to map them to functions at the system level.
+If this variable is non-nil, Emacs will pass them on, allowing the
+system to handle them. */);
+ w32_pass_extra_mouse_buttons_to_system = 0;
+
init_x_parm_symbols ();
DEFVAR_LISP ("x-bitmap-file-path", &Vx_bitmap_file_path,
- "List of directories to search for bitmap files for w32.");
+ doc: /* List of directories to search for bitmap files for w32. */);
Vx_bitmap_file_path = decode_env_path ((char *) 0, "PATH");
DEFVAR_LISP ("x-pointer-shape", &Vx_pointer_shape,
- "The shape of the pointer when over text.\n\
-Changing the value does not affect existing frames\n\
-unless you set the mouse color.");
+ doc: /* The shape of the pointer when over text.
+Changing the value does not affect existing frames
+unless you set the mouse color. */);
Vx_pointer_shape = Qnil;
DEFVAR_LISP ("x-resource-name", &Vx_resource_name,
- "The name Emacs uses to look up resources; for internal use only.\n\
-`x-get-resource' uses this as the first component of the instance name\n\
-when requesting resource values.\n\
-Emacs initially sets `x-resource-name' to the name under which Emacs\n\
-was invoked, or to the value specified with the `-name' or `-rn'\n\
-switches, if present.");
+ 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;
Vx_nontext_pointer_shape = Qnil;
Vx_mode_pointer_shape = Qnil;
DEFVAR_LISP ("x-hourglass-pointer-shape", &Vx_hourglass_pointer_shape,
- "The shape of the pointer when Emacs is busy.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* The shape of the pointer when Emacs is busy.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
Vx_hourglass_pointer_shape = Qnil;
DEFVAR_BOOL ("display-hourglass", &display_hourglass_p,
- "Non-zero means Emacs displays an hourglass pointer on window systems.");
+ doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */);
display_hourglass_p = 1;
DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay,
- "*Seconds to wait before displaying an hourglass pointer.\n\
-Value must be an integer or float.");
+ doc: /* *Seconds to wait before displaying an hourglass pointer.
+Value must be an integer or float. */);
Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
DEFVAR_LISP ("x-sensitive-text-pointer-shape",
&Vx_sensitive_text_pointer_shape,
- "The shape of the pointer when over mouse-sensitive text.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* The shape of the pointer when over mouse-sensitive text.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
Vx_sensitive_text_pointer_shape = Qnil;
DEFVAR_LISP ("x-window-horizontal-drag-cursor",
&Vx_window_horizontal_drag_shape,
- "Pointer shape to use for indicating a window can be dragged horizontally.\n\
-This variable takes effect when you create a new frame\n\
-or when you set the mouse color.");
+ doc: /* Pointer shape to use for indicating a window can be dragged horizontally.
+This variable takes effect when you create a new frame
+or when you set the mouse color. */);
Vx_window_horizontal_drag_shape = Qnil;
DEFVAR_LISP ("x-cursor-fore-pixel", &Vx_cursor_fore_pixel,
- "A string indicating the foreground color of the cursor box.");
+ doc: /* A string indicating the foreground color of the cursor box. */);
Vx_cursor_fore_pixel = Qnil;
DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
- "Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).\n\
-Text larger than this is clipped.");
+ doc: /* Maximum size for tooltips.
+Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,
- "Non-nil if no window manager is in use.\n\
-Emacs doesn't try to figure this out; this is always nil\n\
-unless you set it to something else.");
+ doc: /* Non-nil if no window manager is in use.
+Emacs doesn't try to figure this out; this is always nil
+unless you set it to something else. */);
/* We don't have any way to find this out, so set it to nil
and maybe the user would like to set it to t. */
Vx_no_window_manager = Qnil;
DEFVAR_LISP ("x-pixel-size-width-font-regexp",
&Vx_pixel_size_width_font_regexp,
- "Regexp matching a font name whose width is the same as `PIXEL_SIZE'.\n\
-\n\
-Since Emacs gets width of a font matching with this regexp from\n\
-PIXEL_SIZE field of the name, font finding mechanism gets faster for\n\
-such a font. This is especially effective for such large fonts as\n\
-Chinese, Japanese, and Korean.");
+ doc: /* Regexp matching a font name whose width is the same as `PIXEL_SIZE'.
+
+Since Emacs gets width of a font matching with this regexp from
+PIXEL_SIZE field of the name, font finding mechanism gets faster for
+such a font. This is especially effective for such large fonts as
+Chinese, Japanese, and Korean. */);
Vx_pixel_size_width_font_regexp = Qnil;
DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
- "Time after which cached images are removed from the cache.\n\
-When an image has not been displayed this many seconds, remove it\n\
-from the image cache. Value must be an integer or nil with nil\n\
-meaning don't clear the cache.");
+ doc: /* Time after which cached images are removed from the cache.
+When an image has not been displayed this many seconds, remove it
+from the image cache. Value must be an integer or nil with nil
+meaning don't clear the cache. */);
Vimage_cache_eviction_delay = make_number (30 * 60);
DEFVAR_LISP ("w32-bdf-filename-alist",
&Vw32_bdf_filename_alist,
- "List of bdf fonts and their corresponding filenames.");
+ doc: /* List of bdf fonts and their corresponding filenames. */);
Vw32_bdf_filename_alist = Qnil;
DEFVAR_BOOL ("w32-strict-fontnames",
&w32_strict_fontnames,
- "Non-nil means only use fonts that are exact matches for those requested.\n\
-Default is nil, which allows old fontnames that are not XLFD compliant,\n\
-and allows third-party CJK display to work by specifying false charset\n\
-fields to trick Emacs into translating to Big5, SJIS etc.\n\
-Setting this to t will prevent wrong fonts being selected when\n\
-fontsets are automatically created.");
+ doc: /* Non-nil means only use fonts that are exact matches for those requested.
+Default is nil, which allows old fontnames that are not XLFD compliant,
+and allows third-party CJK display to work by specifying false charset
+fields to trick Emacs into translating to Big5, SJIS etc.
+Setting this to t will prevent wrong fonts being selected when
+fontsets are automatically created. */);
w32_strict_fontnames = 0;
DEFVAR_BOOL ("w32-strict-painting",
&w32_strict_painting,
- "Non-nil means use strict rules for repainting frames.\n\
-Set this to nil to get the old behaviour for repainting; this should\n\
-only be necessary if the default setting causes problems.");
+ doc: /* Non-nil means use strict rules for repainting frames.
+Set this to nil to get the old behaviour for repainting; this should
+only be necessary if the default setting causes problems. */);
w32_strict_painting = 1;
- DEFVAR_LISP ("w32-system-coding-system",
- &Vw32_system_coding_system,
- "Coding system used by Windows system functions, such as for font names.");
- Vw32_system_coding_system = Qnil;
-
DEFVAR_LISP ("w32-charset-info-alist",
&Vw32_charset_info_alist,
- "Alist linking Emacs character sets to Windows fonts\n\
-and codepages. Each entry should be of the form:\n\
-\n\
- (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE))\n\
-\n\
-where CHARSET_NAME is a string used in font names to identify the charset,\n\
-WINDOWS_CHARSET is a symbol that can be one of:\n\
-w32-charset-ansi, w32-charset-default, w32-charset-symbol,\n\
-w32-charset-shiftjis, w32-charset-hangeul, w32-charset-gb2312,\n\
-w32-charset-chinesebig5, "
+ doc: /* Alist linking Emacs character sets to Windows fonts and codepages.
+Each entry should be of the form:
+
+ (CHARSET_NAME . (WINDOWS_CHARSET . CODEPAGE))
+
+where CHARSET_NAME is a string used in font names to identify the charset,
+WINDOWS_CHARSET is a symbol that can be one of:
+w32-charset-ansi, w32-charset-default, w32-charset-symbol,
+w32-charset-shiftjis, w32-charset-hangeul, w32-charset-gb2312,
+w32-charset-chinesebig5,
#ifdef JOHAB_CHARSET
-"w32-charset-johab, w32-charset-hebrew,\n\
-w32-charset-arabic, w32-charset-greek, w32-charset-turkish,\n\
-w32-charset-vietnamese, w32-charset-thai, w32-charset-easteurope,\n\
-w32-charset-russian, w32-charset-mac, w32-charset-baltic,\n"
+w32-charset-johab, w32-charset-hebrew,
+w32-charset-arabic, w32-charset-greek, w32-charset-turkish,
+w32-charset-vietnamese, w32-charset-thai, w32-charset-easteurope,
+w32-charset-russian, w32-charset-mac, w32-charset-baltic,
#endif
#ifdef UNICODE_CHARSET
-"w32-charset-unicode, "
+w32-charset-unicode,
#endif
-"or w32-charset-oem.\n\
-CODEPAGE should be an integer specifying the codepage that should be used\n\
-to display the character set, t to do no translation and output as Unicode,\n\
-or nil to do no translation and output as 8 bit (or multibyte on far-east\n\
-versions of Windows) characters.");
+or w32-charset-oem.
+CODEPAGE should be an integer specifying the codepage that should be used
+to display the character set, t to do no translation and output as Unicode,
+or nil to do no translation and output as 8 bit (or multibyte on far-east
+versions of Windows) characters. */);
Vw32_charset_info_alist = Qnil;
staticpro (&Qw32_charset_ansi);
#ifdef JOHAB_CHARSET
{
static int w32_extra_charsets_defined = 1;
- DEFVAR_BOOL ("w32-extra-charsets-defined", &w32_extra_charsets_defined, "");
+ DEFVAR_BOOL ("w32-extra-charsets-defined", &w32_extra_charsets_defined,
+ doc: /* Internal variable. */);
staticpro (&Qw32_charset_johab);
Qw32_charset_johab = intern ("w32-charset-johab");
{
static int w32_unicode_charset_defined = 1;
DEFVAR_BOOL ("w32-unicode-charset-defined",
- &w32_unicode_charset_defined, "");
+ &w32_unicode_charset_defined,
+ doc: /* Internal variable. */);
staticpro (&Qw32_charset_unicode);
Qw32_charset_unicode = intern ("w32-charset-unicode");
set_frame_fontset_func = x_set_font;
check_window_system_func = check_w32;
-#if 0 /* TODO Image support for W32 */
/* Images. */
Qxbm = intern ("xbm");
staticpro (&Qxbm);
- QCtype = intern (":type");
- staticpro (&QCtype);
QCconversion = intern (":conversion");
staticpro (&QCconversion);
QCheuristic_mask = intern (":heuristic-mask");
staticpro (&QCrelief);
Qpostscript = intern ("postscript");
staticpro (&Qpostscript);
+#if 0 /* TODO: These need entries at top of file. */
QCloader = intern (":loader");
staticpro (&QCloader);
QCbounding_box = intern (":bounding-box");
staticpro (&QCpt_width);
QCpt_height = intern (":pt-height");
staticpro (&QCpt_height);
+#endif
QCindex = intern (":index");
staticpro (&QCindex);
Qpbm = intern ("pbm");
#endif
defsubr (&Sclear_image_cache);
+ defsubr (&Simage_size);
+ defsubr (&Simage_mask_p);
#if GLYPH_DEBUG
defsubr (&Simagep);
defsubr (&Slookup_image);
#endif
-#endif /* TODO */
hourglass_atimer = NULL;
hourglass_shown_p = 0;
-#ifdef TODO /* Tooltip support not complete. */
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);
-#endif
tip_timer = Qnil;
staticpro (&tip_timer);
tip_frame = Qnil;
staticpro (&tip_frame);
+ last_show_tip_args = Qnil;
+ staticpro (&last_show_tip_args);
+
defsubr (&Sx_file_dialog);
}
image_types = NULL;
Vimage_types = Qnil;
-#if 0 /* TODO : Image support for W32 */
+ define_image_type (&pbm_type);
define_image_type (&xbm_type);
+#if 0 /* TODO : Image support for W32 */
define_image_type (&gs_type);
- define_image_type (&pbm_type);
+#endif
#if HAVE_XPM
define_image_type (&xpm_type);
#if HAVE_TIFF
define_image_type (&tiff_type);
#endif
-
+
#if HAVE_GIF
define_image_type (&gif_type);
#endif
#if HAVE_PNG
define_image_type (&png_type);
#endif
-#endif /* TODO */
}
#undef abort