/* Graphical user interface functions for the Microsoft Windows API.
-Copyright (C) 1989, 1992-2014 Free Software Foundation, Inc.
+Copyright (C) 1989, 1992-2015 Free Software Foundation, Inc.
This file is part of GNU Emacs.
extern const char *map_w32_filename (const char *, const char **);
extern char * w32_strerror (int error_no);
-/* If non-NULL, a handle to a frame where to display the hourglass cursor. */
-static HWND hourglass_hwnd = NULL;
-
#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
-Lisp_Object Qundefined_color;
-Lisp_Object Qcancel_timer;
-Lisp_Object Qfont_param;
-Lisp_Object Qhyper;
-Lisp_Object Qsuper;
-Lisp_Object Qmeta;
-Lisp_Object Qalt;
-Lisp_Object Qctrl;
-Lisp_Object Qcontrol;
-Lisp_Object Qshift;
-static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes;
-
-
/* Prefix for system colors. */
#define SYSTEM_COLOR_PREFIX "System"
#define SYSTEM_COLOR_PREFIX_LEN (sizeof (SYSTEM_COLOR_PREFIX) - 1)
/* From w32menu.c */
extern HMENU current_popup_menu;
-static int menubar_in_use = 0;
+int menubar_in_use = 0;
/* From w32uniscribe.c */
extern void syms_of_w32uniscribe (void);
extern int uniscribe_available;
-/* Function prototypes for hourglass support. */
-static void w32_show_hourglass (struct frame *);
-static void w32_hide_hourglass (void);
-
#ifdef WINDOWSNT
/* From w32inevt.c */
extern int faked_key;
the first display on the list. */
struct w32_display_info *
-check_x_display_info (Lisp_Object frame)
+check_x_display_info (Lisp_Object object)
{
- if (NILP (frame))
+ if (NILP (object))
{
struct frame *sf = XFRAME (selected_frame);
else
return &one_w32_display_info;
}
- else if (STRINGP (frame))
- return x_display_info_for_name (frame);
+ else if (TERMINALP (object))
+ {
+ struct terminal *t = decode_live_terminal (object);
+
+ if (t->type != output_w32)
+ error ("Terminal %d is not a W32 display", t->id);
+
+ return t->display_info.w32;
+ }
+ else if (STRINGP (object))
+ return x_display_info_for_name (object);
else
{
struct frame *f;
- CHECK_LIVE_FRAME (frame);
- f = XFRAME (frame);
+ CHECK_LIVE_FRAME (object);
+ f = XFRAME (object);
if (! FRAME_W32_P (f))
error ("Non-W32 frame used");
return FRAME_DISPLAY_INFO (f);
void x_set_menu_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
void x_set_title (struct frame *, Lisp_Object, Lisp_Object);
void x_set_tool_bar_lines (struct frame *, Lisp_Object, Lisp_Object);
-
-
+void x_set_internal_border_width (struct frame *f, Lisp_Object, Lisp_Object);
\f
/* Store the screen positions of frame F into XPTR and YPTR.
{
CHECK_NUMBER (Vx_window_horizontal_drag_shape);
horizontal_drag_cursor
- = XCreateFontCursor (FRAME_X_DISPLAY (f),
+ = XCreateFontCursor (FRAME_W32_DISPLAY (f),
XINT (Vx_window_horizontal_drag_shape));
}
else
horizontal_drag_cursor
- = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_h_double_arrow);
+ = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_h_double_arrow);
if (!NILP (Vx_window_vertical_drag_shape))
{
CHECK_NUMBER (Vx_window_vertical_drag_shape);
vertical_drag_cursor
- = XCreateFontCursor (FRAME_X_DISPLAY (f),
+ = XCreateFontCursor (FRAME_W32_DISPLAY (f),
XINT (Vx_window_vertical_drag_shape));
}
else
vertical_drag_cursor
- = XCreateFontCursor (FRAME_X_DISPLAY (f), XC_sb_v_double_arrow);
+ = XCreateFontCursor (FRAME_W32_DISPLAY (f), XC_sb_v_double_arrow);
/* Check and report errors with the above calls. */
x_check_errors (FRAME_W32_DISPLAY (f), "can't set cursor shape: %s");
unblock_input ();
#endif
}
-
\f
+void
+x_clear_under_internal_border (struct frame *f)
+{
+ int border = FRAME_INTERNAL_BORDER_WIDTH (f);
+
+ /* Clear border if it's larger than before. */
+ if (border != 0)
+ {
+ HDC hdc = get_frame_dc (f);
+ int width = FRAME_PIXEL_WIDTH (f);
+ int height = FRAME_PIXEL_HEIGHT (f);
+
+ block_input ();
+ w32_clear_area (f, hdc, 0, FRAME_TOP_MARGIN_HEIGHT (f), width, border);
+ w32_clear_area (f, hdc, 0, 0, border, height);
+ w32_clear_area (f, hdc, width - border, 0, border, height);
+ w32_clear_area (f, hdc, 0, height - border, width, border);
+ release_frame_dc (f, hdc);
+ unblock_input ();
+ }
+}
+
+
+void
+x_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
+{
+ int border;
+
+ CHECK_TYPE_RANGED_INTEGER (int, arg);
+ border = max (XINT (arg), 0);
+
+ if (border != FRAME_INTERNAL_BORDER_WIDTH (f))
+ {
+ FRAME_INTERNAL_BORDER_WIDTH (f) = border;
+
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ adjust_frame_size (f, -1, -1, 3, 0, Qinternal_border_width);
+
+ if (FRAME_VISIBLE_P (f))
+ x_clear_under_internal_border (f);
+ }
+ }
+}
+
+
void
x_set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
FRAME_MENU_BAR_LINES (f) = 0;
FRAME_MENU_BAR_HEIGHT (f) = 0;
if (nlines)
- FRAME_EXTERNAL_MENU_BAR (f) = 1;
+ {
+ FRAME_EXTERNAL_MENU_BAR (f) = 1;
+ windows_or_buffers_changed = 23;
+ }
else
{
if (FRAME_EXTERNAL_MENU_BAR (f) == 1)
/* Adjust the frame size so that the client (text) dimensions
remain the same. This depends on FRAME_EXTERNAL_MENU_BAR being
- set correctly. */
- x_set_window_size (f, 0, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 1);
- do_pending_window_change (0);
+ set correctly. Note that we resize twice: The first time upon
+ a request from the window manager who wants to keep the height
+ of the outer rectangle (including decorations) unchanged, and a
+ second time because we want to keep the height of the inner
+ rectangle (without the decorations unchanged). */
+ adjust_frame_size (f, -1, -1, 2, 1, Qmenu_bar_lines);
+
+ /* Not sure whether this is needed. */
+ x_clear_under_internal_border (f);
}
- adjust_frame_glyphs (f);
}
void
x_set_tool_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
{
- int delta, nlines, root_height;
- int unit = FRAME_LINE_HEIGHT (f);
+ int nlines;
/* Treat tool bars like menu bars. */
if (FRAME_MINIBUF_ONLY_P (f))
else
nlines = 0;
- /* Make sure we redisplay all windows in this frame. */
- windows_or_buffers_changed = 23;
+ x_change_tool_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
- /* DELTA is in pixels now. */
- delta = (nlines - FRAME_TOOL_BAR_LINES (f)) * unit;
- /* Don't resize the tool-bar to more than we have room for. Note: The
- calculations below and the subsequent call to resize_frame_windows
- are inherently flawed because they can make the toolbar higher than
- the containing frame. */
- if (delta > 0)
- {
- root_height = WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)));
- if (root_height - delta < unit)
- {
- delta = root_height - unit;
- /* When creating a new frame and toolbar mode is enabled, we
- need at least one toolbar line. */
- nlines = max (FRAME_TOOL_BAR_LINES (f) + delta / unit, 1);
- }
- }
+/* Set the pixel height of the tool bar of frame F to HEIGHT. */
+void
+x_change_tool_bar_height (struct frame *f, int height)
+{
+ Lisp_Object frame;
+ int unit = FRAME_LINE_HEIGHT (f);
+ int old_height = FRAME_TOOL_BAR_HEIGHT (f);
+ int lines = (height + unit - 1) / unit;
+ int old_text_height = FRAME_TEXT_HEIGHT (f);
- FRAME_TOOL_BAR_LINES (f) = nlines;
- FRAME_TOOL_BAR_HEIGHT (f) = nlines * FRAME_LINE_HEIGHT (f);
- ++windows_or_buffers_changed;
- resize_frame_windows (f, FRAME_TEXT_HEIGHT (f), 0, 1);
- adjust_frame_glyphs (f);
+ /* Make sure we redisplay all windows in this frame. */
+ windows_or_buffers_changed = 23;
+
+ /* Recalculate tool bar and frame text sizes. */
+ FRAME_TOOL_BAR_HEIGHT (f) = height;
+ FRAME_TOOL_BAR_LINES (f) = lines;
+ /* Store `tool-bar-lines' and `height' frame parameters. */
+ store_frame_param (f, Qtool_bar_lines, make_number (lines));
+ store_frame_param (f, Qheight, make_number (FRAME_LINES (f)));
- /* We also have to make sure that the internal border at the top of
- the frame, below the menu bar or tool bar, is redrawn when the
- tool bar disappears. This is so because the internal border is
- below the tool bar if one is displayed, but is below the menu bar
- if there isn't a tool bar. The tool bar draws into the area
- below the menu bar. */
if (FRAME_W32_WINDOW (f) && FRAME_TOOL_BAR_HEIGHT (f) == 0)
{
clear_frame (f);
clear_current_matrices (f);
}
- /* If the tool bar gets smaller, the internal border below it
- has to be cleared. It was formerly part of the display
- of the larger tool bar, and updating windows won't clear it. */
- if (FRAME_INTERNAL_BORDER_WIDTH (f) != 0 && FRAME_VISIBLE_P (f))
- {
- int height = FRAME_INTERNAL_BORDER_WIDTH (f);
- int width = FRAME_PIXEL_WIDTH (f);
- int y = nlines * unit;
- HDC hdc = get_frame_dc (f);
+ if ((height < old_height) && WINDOWP (f->tool_bar_window))
+ clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
- block_input ();
- w32_clear_area (f, hdc, 0, y, width, height);
- release_frame_dc (f, hdc);
- unblock_input ();
- }
+ /* Recalculate toolbar height. */
+ f->n_tool_bar_rows = 0;
- if (delta < 0 && WINDOWP (f->tool_bar_window))
- clear_glyph_matrix (XWINDOW (f->tool_bar_window)->current_matrix);
+ adjust_frame_size (f, -1, -1, (old_height == 0 || height == 0) ? 2 : 4, 0,
+ Qtool_bar_lines);
- run_window_configuration_change_hook (f);
+ /* adjust_frame_size might not have done anything, garbage frame
+ here. */
+ adjust_frame_glyphs (f);
+ SET_FRAME_GARBAGED (f);
+ if (FRAME_X_WINDOW (f))
+ x_clear_under_internal_border (f);
}
= (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
}
+
+void
+x_set_scroll_bar_default_height (struct frame *f)
+{
+ int unit = FRAME_LINE_HEIGHT (f);
+
+ FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
+ FRAME_CONFIG_SCROLL_BAR_LINES (f)
+ = (FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) + unit - 1) / unit;
+}
\f
/* Subroutines for creating a frame. */
}
static HWND
-w32_createscrollbar (struct frame *f, struct scroll_bar * bar)
+w32_createvscrollbar (struct frame *f, struct scroll_bar * bar)
{
return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
/* Position and size of scroll bar. */
FRAME_W32_WINDOW (f), NULL, hinst, NULL);
}
+static HWND
+w32_createhscrollbar (struct frame *f, struct scroll_bar * bar)
+{
+ return CreateWindow ("SCROLLBAR", "", SBS_HORZ | WS_CHILD | WS_VISIBLE,
+ /* Position and size of scroll bar. */
+ bar->left, bar->top, bar->width, bar->height,
+ FRAME_W32_WINDOW (f), NULL, hinst, NULL);
+}
+
static void
-w32_createwindow (struct frame *f)
+w32_createwindow (struct frame *f, int *coords)
{
HWND hwnd;
RECT rect;
- Lisp_Object top = Qunbound;
- Lisp_Object left = Qunbound;
- struct w32_display_info *dpyinfo = &one_w32_display_info;
+ int top;
+ int left;
rect.left = rect.top = 0;
rect.right = FRAME_PIXEL_WIDTH (f);
if (f->size_hint_flags & USPosition || f->size_hint_flags & PPosition)
{
- XSETINT (left, f->left_pos);
- XSETINT (top, f->top_pos);
+ left = f->left_pos;
+ top = f->top_pos;
}
- else if (EQ (left, Qunbound) && EQ (top, Qunbound))
+ else
{
- /* When called with RES_TYPE_NUMBER, w32_get_arg will return zero
- for anything that is not a number and is not Qunbound. */
- left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
- top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
+ left = coords[0];
+ top = coords[1];
}
FRAME_W32_WINDOW (f) = hwnd
= CreateWindow (EMACS_CLASS,
f->namebuf,
f->output_data.w32->dwStyle | WS_CLIPCHILDREN,
- EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left),
- EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top),
- rect.right - rect.left,
- rect.bottom - rect.top,
+ left, top,
+ rect.right - rect.left, rect.bottom - rect.top,
NULL,
NULL,
hinst,
SetWindowLong (hwnd, WND_FONTWIDTH_INDEX, FRAME_COLUMN_WIDTH (f));
SetWindowLong (hwnd, WND_LINEHEIGHT_INDEX, FRAME_LINE_HEIGHT (f));
SetWindowLong (hwnd, WND_BORDER_INDEX, FRAME_INTERNAL_BORDER_WIDTH (f));
- SetWindowLong (hwnd, WND_SCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
+ SetWindowLong (hwnd, WND_VSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_WIDTH (f));
+ SetWindowLong (hwnd, WND_HSCROLLBAR_INDEX, FRAME_SCROLL_BAR_AREA_HEIGHT (f));
SetWindowLong (hwnd, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
/* Enable drag-n-drop. */
M (WM_EMACS_KILL),
M (WM_EMACS_CREATEWINDOW),
M (WM_EMACS_DONE),
- M (WM_EMACS_CREATESCROLLBAR),
+ M (WM_EMACS_CREATEVSCROLLBAR),
+ M (WM_EMACS_CREATEHSCROLLBAR),
M (WM_EMACS_SHOWWINDOW),
M (WM_EMACS_SETWINDOWPOS),
M (WM_EMACS_DESTROYWINDOW),
M (WM_EMACS_SHOW_CARET),
M (WM_EMACS_HIDE_CARET),
M (WM_EMACS_SETCURSOR),
+ M (WM_EMACS_SHOWCURSOR),
M (WM_EMACS_PAINT),
M (WM_CHAR),
#undef M
the patch for XP is not publicly available until XP SP3,
and older versions will never be patched. */
CoInitialize (NULL);
- w32_createwindow ((struct frame *) msg.wParam);
+ w32_createwindow ((struct frame *) msg.wParam,
+ (int *) msg.lParam);
if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
emacs_abort ();
break;
track_mouse_event_fn (&tme);
track_mouse_window = hwnd;
}
+ case WM_HSCROLL:
case WM_VSCROLL:
if (w32_mouse_move_interval <= 0
|| (msg == WM_MOUSEMOVE && button_state == 0))
return 0;
case WM_WINDOWPOSCHANGING:
- /* Don't restrict the sizing of tip frames. */
- if (frame_resize_pixelwise || hwnd == tip_window)
- return 0;
+ /* Don't restrict the sizing of any kind of frames. If the window
+ manager doesn't, there's no reason to do it ourselves. */
+#if 0
+ if (frame_resize_pixelwise || hwnd == tip_window)
+#endif
+ return 0;
+#if 0
/* Don't restrict the sizing of fullscreened frames, allowing them to be
flush with the sides of the screen. */
f = x_window_to_frame (dpyinfo, hwnd);
DWORD font_width;
DWORD line_height;
DWORD internal_border;
- DWORD scrollbar_extra;
+ DWORD vscrollbar_extra;
+ DWORD hscrollbar_extra;
RECT wr;
wp.length = sizeof (wp);
font_width = GetWindowLong (hwnd, WND_FONTWIDTH_INDEX);
line_height = GetWindowLong (hwnd, WND_LINEHEIGHT_INDEX);
internal_border = GetWindowLong (hwnd, WND_BORDER_INDEX);
- scrollbar_extra = GetWindowLong (hwnd, WND_SCROLLBAR_INDEX);
+ vscrollbar_extra = GetWindowLong (hwnd, WND_VSCROLLBAR_INDEX);
+ hscrollbar_extra = GetWindowLong (hwnd, WND_HSCROLLBAR_INDEX);
leave_crit ();
/* Force width and height of client area to be exact
multiples of the character cell dimensions. */
wdiff = (lppos->cx - (rect.right - rect.left)
- - 2 * internal_border - scrollbar_extra)
+ - 2 * internal_border - vscrollbar_extra)
% font_width;
hdiff = (lppos->cy - (rect.bottom - rect.top)
- - 2 * internal_border)
+ - 2 * internal_border - hscrollbar_extra)
% line_height;
if (wdiff || hdiff)
}
goto dflt;
+#endif
case WM_GETMINMAXINFO:
/* Hack to allow resizing the Emacs frame above the screen size.
return 0;
}
- case WM_EMACS_CREATESCROLLBAR:
- return (LRESULT) w32_createscrollbar ((struct frame *) wParam,
- (struct scroll_bar *) lParam);
+ case WM_EMACS_SHOWCURSOR:
+ {
+ ShowCursor ((BOOL) wParam);
+
+ return 0;
+ }
+
+ case WM_EMACS_CREATEVSCROLLBAR:
+ return (LRESULT) w32_createvscrollbar ((struct frame *) wParam,
+ (struct scroll_bar *) lParam);
+
+ case WM_EMACS_CREATEHSCROLLBAR:
+ return (LRESULT) w32_createhscrollbar ((struct frame *) wParam,
+ (struct scroll_bar *) lParam);
case WM_EMACS_SHOWWINDOW:
return ShowWindow ((HWND) wParam, (WPARAM) lParam);
my_create_window (struct frame * f)
{
MSG msg;
+ static int coords[2];
+ Lisp_Object left, top;
+ struct w32_display_info *dpyinfo = &one_w32_display_info;
+
+ /* When called with RES_TYPE_NUMBER, x_get_arg will return zero for
+ anything that is not a number and is not Qunbound. */
+ left = x_get_arg (dpyinfo, Qnil, Qleft, "left", "Left", RES_TYPE_NUMBER);
+ top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER);
+ if (EQ (left, Qunbound))
+ coords[0] = CW_USEDEFAULT;
+ else
+ coords[0] = XINT (left);
+ if (EQ (top, Qunbound))
+ coords[1] = CW_USEDEFAULT;
+ else
+ coords[1] = XINT (top);
- if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0))
+ if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
+ (WPARAM)f, (LPARAM)coords))
emacs_abort ();
GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE);
}
SetWindowLong (tip_window, WND_BACKGROUND_INDEX, FRAME_BACKGROUND_PIXEL (f));
/* Tip frames have no scrollbars. */
- SetWindowLong (tip_window, WND_SCROLLBAR_INDEX, 0);
+ SetWindowLong (tip_window, WND_VSCROLLBAR_INDEX, 0);
+ SetWindowLong (tip_window, WND_HSCROLLBAR_INDEX, 0);
/* Do this to discard the default setting specified by our parent. */
ShowWindow (tip_window, SW_HIDE);
Lisp_Object name;
int minibuffer_only = 0;
long window_prompting = 0;
- int width, height;
ptrdiff_t count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
Lisp_Object display;
XSETFRAME (frame, f);
- /* By default, make scrollbars the system standard width. */
- x_set_scroll_bar_default_width (f);
+ /* By default, make scrollbars the system standard width and height. */
+ FRAME_CONFIG_SCROLL_BAR_WIDTH (f) = GetSystemMetrics (SM_CXVSCROLL);
+ FRAME_CONFIG_SCROLL_BAR_HEIGHT (f) = GetSystemMetrics (SM_CXHSCROLL);
f->terminal = dpyinfo->terminal;
#endif /* GLYPH_DEBUG */
/* Specify the parent under which to make this window. */
-
if (!NILP (parent))
{
f->output_data.w32->parent_desc = (Window) XFASTINT (parent);
{
fset_name (f, name);
f->explicit_name = 1;
- /* use the frame's title when getting resources for this frame. */
+ /* Use the frame's title when getting resources for this frame. */
specbind (Qx_resource_name, name);
}
x_default_parameter (f, parameters, Qfont_backend, Qnil,
"fontBackend", "FontBackend", RES_TYPE_STRING);
+
/* Extract the window parameters from the supplied values
that are needed to determine window geometry. */
x_default_font_parameter (f, parameters);
+
x_default_parameter (f, parameters, Qborder_width, make_number (2),
"borderWidth", "BorderWidth", RES_TYPE_NUMBER);
"internalBorder", "InternalBorder", RES_TYPE_NUMBER);
if (! EQ (value, Qunbound))
parameters = Fcons (Fcons (Qinternal_border_width, value),
- parameters);
+ parameters);
}
/* Default internalBorderWidth to 0 on Windows to match other programs. */
x_default_parameter (f, parameters, Qinternal_border_width, make_number (0),
NULL, NULL, RES_TYPE_NUMBER);
x_default_parameter (f, parameters, Qvertical_scroll_bars, Qright,
"verticalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
+ x_default_parameter (f, parameters, Qhorizontal_scroll_bars, Qnil,
+ "horizontalScrollBars", "ScrollBars", RES_TYPE_SYMBOL);
/* Also do the stuff which must be set before the window exists. */
x_default_parameter (f, parameters, Qforeground_color, build_string ("black"),
"rightFringe", "RightFringe", RES_TYPE_NUMBER);
/* Process alpha here (Bug#16619). */
x_default_parameter (f, parameters, Qalpha, Qnil,
- "alpha", "Alpha", RES_TYPE_NUMBER);
+ "alpha", "Alpha", RES_TYPE_NUMBER);
- /* Init faces before x_default_parameter is called for scroll-bar
- parameters because that function calls x_set_scroll_bar_width,
- which calls change_frame_size, which calls Fset_window_buffer,
- which runs hooks, which call Fvertical_motion. At the end, we
- end up in init_iterator with a null face cache, which should not
- happen. */
+ /* Init faces first since we need the frame's column width/line
+ height in various occasions. */
init_frame_faces (f);
- /* Avoid calling window-configuration-change-hook; otherwise we
- could get an infloop in next_frame since the frame is not yet in
- Vframe_list. */
- {
- ptrdiff_t count2 = SPECPDL_INDEX ();
-
- record_unwind_protect (unwind_create_frame_1, inhibit_lisp_code);
- inhibit_lisp_code = Qt;
-
- /* PXW: This is a duplicate from below. We have to do it here since
- otherwise x_set_tool_bar_lines will work with the character sizes
- installed by init_frame_faces while the frame's pixel size is still
- calculated from a character size of 1 and we subsequently hit the
- eassert (height >= 0) assertion in window_box_height. The
- non-pixelwise code apparently worked around this because it had one
- frame line vs one toolbar line which left us with a zero root
- window height which was obviously wrong as well ... */
- change_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
- FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 1, 0, 0, 1);
-
- /* The X resources controlling the menu-bar and tool-bar are
- processed specially at startup, and reflected in the mode
- variables; ignore them here. */
- x_default_parameter (f, parameters, Qmenu_bar_lines,
- NILP (Vmenu_bar_mode)
- ? make_number (0) : make_number (1),
- NULL, NULL, RES_TYPE_NUMBER);
- x_default_parameter (f, parameters, Qtool_bar_lines,
- NILP (Vtool_bar_mode)
- ? make_number (0) : make_number (1),
- NULL, NULL, RES_TYPE_NUMBER);
-
- unbind_to (count2, Qnil);
- }
+ /* The following call of change_frame_size is needed since otherwise
+ x_set_tool_bar_lines will already work with the character sizes
+ installed by init_frame_faces while the frame's pixel size is
+ still calculated from a character size of 1 and we subsequently
+ hit the (height >= 0) assertion in window_box_height.
+
+ The non-pixelwise code apparently worked around this because it
+ had one frame line vs one toolbar line which left us with a zero
+ root window height which was obviously wrong as well ... */
+ adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f),
+ FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qnil);
+
+ /* The X resources controlling the menu-bar and tool-bar are
+ processed specially at startup, and reflected in the mode
+ variables; ignore them here. */
+ x_default_parameter (f, parameters, Qmenu_bar_lines,
+ NILP (Vmenu_bar_mode)
+ ? make_number (0) : make_number (1),
+ NULL, NULL, RES_TYPE_NUMBER);
+ x_default_parameter (f, parameters, Qtool_bar_lines,
+ NILP (Vtool_bar_mode)
+ ? make_number (0) : make_number (1),
+ NULL, NULL, RES_TYPE_NUMBER);
x_default_parameter (f, parameters, Qbuffer_predicate, Qnil,
"bufferPredicate", "BufferPredicate", RES_TYPE_SYMBOL);
x_default_parameter (f, parameters, Qtitle, Qnil,
"title", "Title", RES_TYPE_STRING);
x_default_parameter (f, parameters, Qfullscreen, Qnil,
- "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
+ "fullscreen", "Fullscreen", RES_TYPE_SYMBOL);
f->output_data.w32->dwStyle = WS_OVERLAPPEDWINDOW;
f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
"cursorType", "CursorType", RES_TYPE_SYMBOL);
x_default_parameter (f, parameters, Qscroll_bar_width, Qnil,
"scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER);
+ x_default_parameter (f, parameters, Qscroll_bar_height, Qnil,
+ "scrollBarHeight", "ScrollBarHeight", RES_TYPE_NUMBER);
- /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
- Change will not be effected unless different from the current
- FRAME_LINES (f). */
- width = FRAME_TEXT_WIDTH (f);
- height = FRAME_TEXT_HEIGHT (f);
- FRAME_TEXT_HEIGHT (f) = 0;
- SET_FRAME_WIDTH (f, 0);
- change_frame_size (f, width, height, 1, 0, 0, 1);
+ /* Allow x_set_window_size, now. */
+ f->can_x_set_window_size = true;
+
+ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 0, 1, Qnil);
/* Tell the server what size and position, etc, we want, and how
badly we want them. This should be done after we have the menu
return Qnil;
}
-static BOOL CALLBACK
+static BOOL CALLBACK ALIGN_STACK
w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
{
Lisp_Object *monitor_list = (Lisp_Object *) dwData;
{
char basename[ MAX_PATH ], *str;
- strcpy (basename, SDATA (Vinvocation_name));
+ lispstpcpy (basename, Vinvocation_name);
str = strrchr (basename, '.');
if (str) *str = 0;
Vinvocation_name = build_string (basename);
#endif /* TODO */
-\f
-/***********************************************************************
- Busy cursor
- ***********************************************************************/
-
-void
-w32_note_current_window (void)
-{
- struct frame * f = SELECTED_FRAME ();
-
- if (!FRAME_W32_P (f))
- return;
-
- hourglass_hwnd = FRAME_W32_WINDOW (f);
-}
-
-void
-show_hourglass (struct atimer *timer)
-{
- struct frame *f;
-
- hourglass_atimer = NULL;
-
- block_input ();
- f = x_window_to_frame (&one_w32_display_info,
- hourglass_hwnd);
-
- if (f)
- f->output_data.w32->hourglass_p = 0;
- else
- f = SELECTED_FRAME ();
-
- if (!FRAME_W32_P (f))
- {
- unblock_input ();
- return;
- }
-
- w32_show_hourglass (f);
- unblock_input ();
-}
-
-void
-hide_hourglass (void)
-{
- block_input ();
- w32_hide_hourglass ();
- unblock_input ();
-}
-
-
-/* Display an hourglass cursor. Set the hourglass_p flag in display info
- to indicate that an hourglass cursor is shown. */
-
-static void
-w32_show_hourglass (struct frame *f)
-{
- if (!hourglass_shown_p)
- {
- f->output_data.w32->hourglass_p = 1;
- if (!menubar_in_use && !current_popup_menu)
- SetCursor (f->output_data.w32->hourglass_cursor);
- hourglass_shown_p = 1;
- }
-}
-
-
-/* Hide the hourglass cursor on all frames, if it is currently shown. */
-
-static void
-w32_hide_hourglass (void)
-{
- if (hourglass_shown_p)
- {
- struct frame *f = x_window_to_frame (&one_w32_display_info,
- hourglass_hwnd);
- if (f)
- f->output_data.w32->hourglass_p = 0;
- else
- /* If frame was deleted, restore to selected frame's cursor. */
- f = SELECTED_FRAME ();
-
- if (FRAME_W32_P (f))
- SetCursor (f->output_data.w32->current_cursor);
- else
- /* No cursors on non GUI frames - restore to stock arrow cursor. */
- SetCursor (w32_load_cursor (IDC_ARROW));
-
- hourglass_shown_p = 0;
- }
-}
-
-
-\f
/***********************************************************************
Tool tips
***********************************************************************/
f->wants_modeline = 0;
XSETFRAME (frame, f);
- buffer = Fget_buffer_create (build_string (" *tip*"));
+ AUTO_STRING (tip, " *tip*");
+ buffer = Fget_buffer_create (tip);
/* Use set_window_buffer instead of Fset_window_buffer (see
discussion of bug#11984, bug#12025, bug#12026). */
set_window_buffer (FRAME_ROOT_WINDOW (f), buffer, 0, 0);
"cursorColor", "Foreground", RES_TYPE_STRING);
x_default_parameter (f, parms, Qborder_color, build_string ("black"),
"borderColor", "BorderColor", RES_TYPE_STRING);
+ x_default_parameter (f, parms, Qalpha, Qnil,
+ "alpha", "Alpha", RES_TYPE_NUMBER);
- /* Init faces before x_default_parameter is called for scroll-bar
- parameters because that function calls x_set_scroll_bar_width,
- which calls change_frame_size, which calls Fset_window_buffer,
- which runs hooks, which call Fvertical_motion. At the end, we
- end up in init_iterator with a null face cache, which should not
- happen. */
+ /* Init faces before x_default_parameter is called for the
+ scroll-bar-width parameter because otherwise we 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;
from the current FRAME_LINES (f). */
width = FRAME_COLS (f);
height = FRAME_LINES (f);
- FRAME_LINES (f) = 0;
SET_FRAME_COLS (f, 0);
- change_frame_size (f, width, height, 1, 0, 0, 0);
+ SET_FRAME_LINES (f, 0);
+ adjust_frame_size (f, width * FRAME_COLUMN_WIDTH (f),
+ height * FRAME_LINE_HEIGHT (f), 0, 1, Qnil);
/* Add `tooltip' frame parameter's default value. */
if (NILP (Fframe_parameter (frame, Qtooltip)))
below. And the frame needs to be on Vframe_list or making it
visible won't work. */
Vframe_list = Fcons (frame, Vframe_list);
+ f->can_x_set_window_size = true;
/* Setting attributes of faces of the tooltip frame from resources
and similar will increment face_change_count, which leads to the
place the cursor there. Don't include the width of
this glyph. */
last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
- if (INTEGERP (last->object))
+ if (NILP (last->object))
row_width -= last->pixel_width;
}
else
Don't count that glyph. */
struct glyph *g = row->glyphs[TEXT_AREA];
- if (g->type == STRETCH_GLYPH && INTEGERP (g->object))
+ if (g->type == STRETCH_GLYPH && NILP (g->object))
{
row_width -= g->pixel_width;
seen_reversed_p = 1;
if (row->used[TEXT_AREA] && !row->reversed_p)
{
last = &row->glyphs[TEXT_AREA][row->used[TEXT_AREA] - 1];
- if (INTEGERP (last->object))
+ if (NILP (last->object))
row_width -= last->pixel_width;
}
}
/* Draw into the window. */
- w->must_be_updated_p = 1;
- update_single_window (w, 1);
+ w->must_be_updated_p = true;
+ update_single_window (w);
unblock_input ();
This function is only defined on NS, MS Windows, and X Windows with the
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
-Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories. */)
+Otherwise, if ONLY-DIR-P is non-nil, the user can only select directories.
+On Windows 7 and later, the file selection dialog "remembers" the last
+directory where the user selected a file, and will open that directory
+instead of DIR on subsequent invocations of this function with the same
+value of DIR as in previous invocations; this is standard Windows behavior. */)
(Lisp_Object prompt, Lisp_Object dir, Lisp_Object default_filename, Lisp_Object mustmatch, Lisp_Object only_dir_p)
{
/* Filter index: 1: All Files, 2: Directories only */
Lisp_Object absdoc_encoded = ENCODE_FILE (absdoc);
if (faccessat (AT_FDCWD, SSDATA (absdoc_encoded), F_OK, AT_EACCESS) == 0)
- document = absdoc_encoded;
+ {
+ /* ShellExecute fails if DOCUMENT is a UNC with forward
+ slashes (expand-file-name above converts all backslashes
+ to forward slashes). Now that we know DOCUMENT is a
+ file, we can mirror all forward slashes into backslashes. */
+ unixtodos_filename (SSDATA (absdoc_encoded));
+ document = absdoc_encoded;
+ }
else
document = ENCODE_FILE (document);
}
/* Notify input thread about new hot-key definition, so that it
takes effect without needing to switch focus. */
PostThreadMessage (dwWindowsThreadId, WM_EMACS_REGISTER_HOT_KEY,
- (WPARAM) XLI (key), 0);
+ (WPARAM) XINT (key), 0);
}
return key;
return Qt;
}
+DEFUN ("w32-frame-menu-bar-size", Fw32_frame_menu_bar_size, Sw32_frame_menu_bar_size, 0, 1, 0,
+ doc: /* Return sizes of menu bar on frame FRAME.
+The return value is a list of four elements: The current width and
+height of FRAME's menu bar in pixels, the height of one menu bar line in
+a wrapped menu bar in pixels, and the height of a single line menu bar
+in pixels.
+
+If FRAME is omitted or nil, the selected frame is used. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_any_frame (frame);
+ MENUBARINFO menu_bar;
+ int width, height, single_height, wrapped_height;
+
+ block_input ();
+
+ single_height = GetSystemMetrics (SM_CYMENU);
+ wrapped_height = GetSystemMetrics (SM_CYMENUSIZE);
+ menu_bar.cbSize = sizeof (menu_bar);
+ menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
+ menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
+ GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
+ width = menu_bar.rcBar.right - menu_bar.rcBar.left;
+ height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
+
+ unblock_input ();
+
+ return list4 (make_number (width), make_number (height),
+ make_number (wrapped_height), make_number (single_height));
+}
+
DEFUN ("w32-frame-rect", Fw32_frame_rect, Sw32_frame_rect, 0, 2, 0,
doc: /* Return boundary rectangle of FRAME in screen coordinates.
FRAME must be a live frame and defaults to the selected one.
struct frame *f = decode_live_frame (frame);
RECT rect;
+ block_input ();
+
if (!NILP (client))
GetClientRect (FRAME_W32_WINDOW (f), &rect);
else
GetWindowRect (FRAME_W32_WINDOW (f), &rect);
+ unblock_input ();
+
return list4 (make_number (rect.left), make_number (rect.top),
make_number (rect.right), make_number (rect.bottom));
}
+DEFUN ("x-frame-geometry", Fx_frame_geometry, Sx_frame_geometry, 0, 1, 0,
+ doc: /* Return geometric attributes of frame FRAME.
+FRAME must be a live frame and defaults to the selected one.
+
+The return value is an association list containing the following
+elements (all size values are in pixels).
+
+- `frame-outer-size' is a cons of the outer width and height of FRAME.
+ The outer size includes the title bar and the external borders as well
+ as any menu and/or tool bar of frame.
+
+- `border' is a cons of the horizontal and vertical width of FRAME's
+ external borders.
+
+- `title-bar-height' is the height of the title bar of FRAME.
+
+- `menu-bar-external' if `t' means the menu bar is by default external
+ (not included in the inner size of FRAME).
+
+- `menu-bar-size' is a cons of the width and height of the menu bar of
+ FRAME.
+
+- `tool-bar-external' if `t' means the tool bar is by default external
+ (not included in the inner size of FRAME).
+
+- `tool-bar-side' tells tells on which side the tool bar on FRAME is by
+ default and can be one of `left', `top', `right' or `bottom'.
+
+- `tool-bar-size' is a cons of the width and height of the tool bar of
+ FRAME.
+
+- `frame-inner-size' is a cons of the inner width and height of FRAME.
+ This excludes FRAME's title bar and external border as well as any
+ external menu and/or tool bar. */)
+ (Lisp_Object frame)
+{
+ struct frame *f = decode_live_frame (frame);
+ Lisp_Object geometry = Qnil;
+ RECT frame_outer_edges, frame_inner_edges;
+ MENUBARINFO menu_bar;
+ int border_width, border_height, title_height;
+ int single_bar_height, wrapped_bar_height, menu_bar_height;
+ Lisp_Object fullscreen = Fframe_parameter (frame, Qfullscreen);
+
+ block_input ();
+
+ /* Outer frame rectangle, including outer borders and title bar. */
+ GetWindowRect (FRAME_W32_WINDOW (f), &frame_outer_edges);
+ /* Inner frame rectangle, excluding borders and title bar. */
+ GetClientRect (FRAME_W32_WINDOW (f), &frame_inner_edges);
+ /* Outer border. */
+ border_width = GetSystemMetrics (SM_CXFRAME);
+ border_height = GetSystemMetrics (SM_CYFRAME);
+ /* Title bar. */
+ title_height = GetSystemMetrics (SM_CYCAPTION);
+ /* Menu bar. */
+ menu_bar.cbSize = sizeof (menu_bar);
+ menu_bar.rcBar.right = menu_bar.rcBar.left = 0;
+ menu_bar.rcBar.top = menu_bar.rcBar.bottom = 0;
+ GetMenuBarInfo (FRAME_W32_WINDOW (f), 0xFFFFFFFD, 0, &menu_bar);
+ single_bar_height = GetSystemMetrics (SM_CYMENU);
+ wrapped_bar_height = GetSystemMetrics (SM_CYMENUSIZE);
+ unblock_input ();
+
+ menu_bar_height = menu_bar.rcBar.bottom - menu_bar.rcBar.top;
+ /* Fix menu bar height reported by GetMenuBarInfo. */
+ if (menu_bar_height > single_bar_height)
+ /* A wrapped menu bar. */
+ menu_bar_height += single_bar_height - wrapped_bar_height;
+ else if (menu_bar_height > 0)
+ /* A single line menu bar. */
+ menu_bar_height = single_bar_height;
+
+ return
+ listn (CONSTYPE_PURE, 10,
+ Fcons (Qframe_position,
+ Fcons (make_number (frame_outer_edges.left),
+ make_number (frame_outer_edges.top))),
+ Fcons (Qframe_outer_size,
+ Fcons (make_number
+ (frame_outer_edges.right - frame_outer_edges.left),
+ make_number
+ (frame_outer_edges.bottom - frame_outer_edges.top))),
+ Fcons (Qexternal_border_size,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? Fcons (make_number (0), make_number (0))
+ : Fcons (make_number (border_width),
+ make_number (border_height)))),
+ Fcons (Qtitle_height,
+ ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
+ ? make_number (0)
+ : make_number (title_height))),
+ Fcons (Qmenu_bar_external, Qt),
+ Fcons (Qmenu_bar_size,
+ Fcons (make_number
+ (menu_bar.rcBar.right - menu_bar.rcBar.left),
+ make_number (menu_bar_height))),
+ Fcons (Qtool_bar_external, Qnil),
+ Fcons (Qtool_bar_position, Qtop),
+ Fcons (Qtool_bar_size,
+ Fcons (make_number (FRAME_TOOL_BAR_LINES (f)
+ ? (FRAME_PIXEL_WIDTH (f)
+ - 2 * FRAME_INTERNAL_BORDER_WIDTH (f))
+ : 0),
+ make_number (FRAME_TOOL_BAR_HEIGHT (f)))),
+ Fcons (Qframe_inner_size,
+ Fcons (make_number
+ (frame_inner_edges.right - frame_inner_edges.left),
+ make_number
+ (frame_inner_edges.bottom - frame_inner_edges.top))));
+}
+
DEFUN ("w32-battery-status", Fw32_battery_status, Sw32_battery_status, 0, 0, 0,
doc: /* Get power status information from Windows system.
x_set_mouse_color,
x_explicitly_set_name,
x_set_scroll_bar_width,
+ x_set_scroll_bar_height,
x_set_title,
x_set_unsplittable,
x_set_vertical_scroll_bars,
+ x_set_horizontal_scroll_bars,
x_set_visibility,
x_set_tool_bar_lines,
0, /* x_set_scroll_bar_foreground, */
0, /* x_set_scroll_bar_background, */
x_set_screen_gamma,
x_set_line_spacing,
- x_set_fringe_width,
- x_set_fringe_width,
+ x_set_left_fringe,
+ x_set_right_fringe,
0, /* x_set_wait_for_wm, */
x_set_fullscreen,
x_set_font_backend,
defsubr (&Sx_open_connection);
defsubr (&Sx_close_connection);
defsubr (&Sx_display_list);
+ defsubr (&Sx_frame_geometry);
defsubr (&Sx_synchronize);
/* W32 specific functions */
defsubr (&Sw32_toggle_lock_key);
defsubr (&Sw32_window_exists_p);
defsubr (&Sw32_frame_rect);
+ defsubr (&Sw32_frame_menu_bar_size);
defsubr (&Sw32_battery_status);
#ifdef WINDOWSNT
#endif
defsubr (&Sset_message_beep);
-
- hourglass_hwnd = NULL;
-
defsubr (&Sx_show_tip);
defsubr (&Sx_hide_tip);
tip_timer = Qnil;