#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
-/* Nonzero if using Windows. */
-
-static int w32_in_use;
-
Lisp_Object Qsuppress_icon;
Lisp_Object Qundefined_color;
Lisp_Object Qcancel_timer;
Lisp_Object Qctrl;
Lisp_Object Qcontrol;
Lisp_Object Qshift;
+static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes;
/* Prefix for system colors. */
#ifndef MONITOR_DEFAULT_TO_NEAREST
#define MONITOR_DEFAULT_TO_NEAREST 2
#endif
+#ifndef MONITORINFOF_PRIMARY
+#define MONITORINFOF_PRIMARY 1
+#endif
+#ifndef SM_XVIRTUALSCREEN
+#define SM_XVIRTUALSCREEN 76
+#endif
+#ifndef SM_YVIRTUALSCREEN
+#define SM_YVIRTUALSCREEN 77
+#endif
/* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't.
To avoid a compile error on one or the other, redefine with a new name. */
struct MONITOR_INFO
DWORD dwFlags;
};
+#ifndef CCHDEVICENAME
+#define CCHDEVICENAME 32
+#endif
+struct MONITOR_INFO_EX
+{
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+ char szDevice[CCHDEVICENAME];
+};
+
/* Reportedly, MSVC does not have this in its headers. */
#if defined (_MSC_VER) && _WIN32_WINNT < 0x0500
DECLARE_HANDLE(HMONITOR);
typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags);
typedef BOOL (WINAPI * GetMonitorInfo_Proc)
(IN HMONITOR monitor, OUT struct MONITOR_INFO* info);
+typedef HMONITOR (WINAPI * MonitorFromWindow_Proc)
+ (IN HWND hwnd, IN DWORD dwFlags);
+typedef BOOL CALLBACK (* MonitorEnum_Proc)
+ (IN HMONITOR monitor, IN HDC hdc, IN RECT *rcMonitor, IN LPARAM dwData);
+typedef BOOL (WINAPI * EnumDisplayMonitors_Proc)
+ (IN HDC hdc, IN RECT *rcClip, IN MonitorEnum_Proc fnEnum, IN LPARAM dwData);
TrackMouseEvent_Proc track_mouse_event_fn = NULL;
ImmGetCompositionString_Proc get_composition_string_fn = NULL;
ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL;
MonitorFromPoint_Proc monitor_from_point_fn = NULL;
GetMonitorInfo_Proc get_monitor_info_fn = NULL;
+MonitorFromWindow_Proc monitor_from_window_fn = NULL;
+EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL;
#ifdef NTGUI_UNICODE
#define unicode_append_menu AppendMenuW
static unsigned int sound_type = 0xFFFFFFFF;
#define MB_EMACS_SILENT (0xFFFFFFFF - 1)
-\f
-/* Error if we are not connected to MS-Windows. */
-void
-check_w32 (void)
-{
- if (! w32_in_use)
- error ("MS-Windows not in use or not initialized");
-}
-
-/* Nonzero if we can use mouse menus.
- You should not call this unless HAVE_MENUS is defined. */
-
-int
-have_menus_p (void)
-{
- return w32_in_use;
-}
-
-/* Extract a frame as a FRAME_PTR, defaulting to the selected frame
- and checking validity for W32. */
-
-FRAME_PTR
-check_x_frame (Lisp_Object frame)
-{
- struct frame *f = decode_live_frame (frame);
-
- if (! FRAME_W32_P (f))
- error ("Non-W32 frame used");
- return f;
-}
-
/* Let the user specify a display with a frame.
nil stands for the selected frame--or, if that is not a w32 frame,
the first display on the list. */
struct frame *sf = XFRAME (selected_frame);
if (FRAME_W32_P (sf) && FRAME_LIVE_P (sf))
- return FRAME_W32_DISPLAY_INFO (sf);
+ return FRAME_DISPLAY_INFO (sf);
else
return &one_w32_display_info;
}
return x_display_info_for_name (frame);
else
{
- FRAME_PTR f;
+ struct frame *f;
CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
if (! FRAME_W32_P (f))
error ("Non-W32 frame used");
- return FRAME_W32_DISPLAY_INFO (f);
+ return FRAME_DISPLAY_INFO (f);
}
}
\f
FOR_EACH_FRAME (tail, frame)
{
f = XFRAME (frame);
- if (!FRAME_W32_P (f) || FRAME_W32_DISPLAY_INFO (f) != dpyinfo)
+ if (!FRAME_W32_P (f) || FRAME_DISPLAY_INFO (f) != dpyinfo)
continue;
if (FRAME_W32_WINDOW (f) == wdesc)
\f
static Lisp_Object unwind_create_frame (Lisp_Object);
-static Lisp_Object unwind_create_tip_frame (Lisp_Object);
+static void unwind_create_tip_frame (Lisp_Object);
static void my_create_window (struct frame *);
static void my_create_tip_window (struct frame *);
not Emacs's own window. */
void
-x_real_positions (FRAME_PTR f, int *xptr, int *yptr)
+x_real_positions (struct frame *f, int *xptr, int *yptr)
{
POINT pt;
RECT rect;
*yptr = rect.top;
}
+/* Returns the window rectangle appropriate for the given fullscreen mode.
+ The normal rect parameter was the window's rectangle prior to entering
+ fullscreen mode. If multiple monitor support is available, the nearest
+ monitor to the window is chosen. */
+
+void
+w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
+{
+ struct MONITOR_INFO mi = { sizeof(mi) };
+ if (monitor_from_window_fn && get_monitor_info_fn)
+ {
+ HMONITOR monitor =
+ monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
+ get_monitor_info_fn (monitor, &mi);
+ }
+ else
+ {
+ mi.rcMonitor.left = 0;
+ mi.rcMonitor.top = 0;
+ mi.rcMonitor.right = GetSystemMetrics (SM_CXSCREEN);
+ mi.rcMonitor.bottom = GetSystemMetrics (SM_CYSCREEN);
+ mi.rcWork.left = 0;
+ mi.rcWork.top = 0;
+ mi.rcWork.right = GetSystemMetrics (SM_CXMAXIMIZED);
+ mi.rcWork.bottom = GetSystemMetrics (SM_CYMAXIMIZED);
+ }
+
+ switch (fsmode)
+ {
+ case FULLSCREEN_BOTH:
+ rect->left = mi.rcMonitor.left;
+ rect->top = mi.rcMonitor.top;
+ rect->right = mi.rcMonitor.right;
+ rect->bottom = mi.rcMonitor.bottom;
+ break;
+ case FULLSCREEN_MAXIMIZED:
+ rect->left = mi.rcWork.left;
+ rect->top = mi.rcWork.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_WIDTH:
+ rect->left = mi.rcWork.left;
+ rect->top = normal.top;
+ rect->right = mi.rcWork.right;
+ rect->bottom = normal.bottom;
+ break;
+ case FULLSCREEN_HEIGHT:
+ rect->left = normal.left;
+ rect->top = mi.rcWork.top;
+ rect->right = normal.right;
+ rect->bottom = mi.rcWork.bottom;
+ break;
+ case FULLSCREEN_NONE:
+ default:
+ *rect = normal;
+ break;
+ }
+}
+
\f
DEFUN ("w32-define-rgb-color", Fw32_define_rgb_color,
}
void
-w32_regenerate_palette (FRAME_PTR f)
+w32_regenerate_palette (struct frame *f)
{
struct w32_palette_entry * list;
LOGPALETTE * log_palette;
int i;
/* don't bother trying to create palette if not supported */
- if (! FRAME_W32_DISPLAY_INFO (f)->has_palette)
+ if (! FRAME_DISPLAY_INFO (f)->has_palette)
return;
log_palette = (LOGPALETTE *)
alloca (sizeof (LOGPALETTE) +
- FRAME_W32_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
+ FRAME_DISPLAY_INFO (f)->num_colors * sizeof (PALETTEENTRY));
log_palette->palVersion = 0x300;
- log_palette->palNumEntries = FRAME_W32_DISPLAY_INFO (f)->num_colors;
+ log_palette->palNumEntries = FRAME_DISPLAY_INFO (f)->num_colors;
- list = FRAME_W32_DISPLAY_INFO (f)->color_list;
+ list = FRAME_DISPLAY_INFO (f)->color_list;
for (i = 0;
- i < FRAME_W32_DISPLAY_INFO (f)->num_colors;
+ i < FRAME_DISPLAY_INFO (f)->num_colors;
i++, list = list->next)
log_palette->palPalEntry[i] = list->entry;
enter_crit ();
- if (FRAME_W32_DISPLAY_INFO (f)->palette)
- DeleteObject (FRAME_W32_DISPLAY_INFO (f)->palette);
- FRAME_W32_DISPLAY_INFO (f)->palette = new_palette;
+ if (FRAME_DISPLAY_INFO (f)->palette)
+ DeleteObject (FRAME_DISPLAY_INFO (f)->palette);
+ FRAME_DISPLAY_INFO (f)->palette = new_palette;
/* Realize display palette and garbage all frames. */
release_frame_dc (f, get_frame_dc (f));
#if 0
/* Keep these around in case we ever want to track color usage. */
void
-w32_map_color (FRAME_PTR f, COLORREF color)
+w32_map_color (struct frame *f, COLORREF color)
{
- struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
+ struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list;
if (NILP (Vw32_enable_palette))
return;
list = xmalloc (sizeof (struct w32_palette_entry));
SET_W32_COLOR (list->entry, color);
list->refcount = 1;
- list->next = FRAME_W32_DISPLAY_INFO (f)->color_list;
- FRAME_W32_DISPLAY_INFO (f)->color_list = list;
- FRAME_W32_DISPLAY_INFO (f)->num_colors++;
+ list->next = FRAME_DISPLAY_INFO (f)->color_list;
+ FRAME_DISPLAY_INFO (f)->color_list = list;
+ FRAME_DISPLAY_INFO (f)->num_colors++;
/* set flag that palette must be regenerated */
- FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
+ FRAME_DISPLAY_INFO (f)->regen_palette = TRUE;
}
void
-w32_unmap_color (FRAME_PTR f, COLORREF color)
+w32_unmap_color (struct frame *f, COLORREF color)
{
- struct w32_palette_entry * list = FRAME_W32_DISPLAY_INFO (f)->color_list;
- struct w32_palette_entry **prev = &FRAME_W32_DISPLAY_INFO (f)->color_list;
+ struct w32_palette_entry * list = FRAME_DISPLAY_INFO (f)->color_list;
+ struct w32_palette_entry **prev = &FRAME_DISPLAY_INFO (f)->color_list;
if (NILP (Vw32_enable_palette))
return;
{
*prev = list->next;
xfree (list);
- FRAME_W32_DISPLAY_INFO (f)->num_colors--;
+ FRAME_DISPLAY_INFO (f)->num_colors--;
break;
}
else
}
/* set flag that palette must be regenerated */
- FRAME_W32_DISPLAY_INFO (f)->regen_palette = TRUE;
+ FRAME_DISPLAY_INFO (f)->regen_palette = TRUE;
}
#endif
If ALLOC is nonzero, allocate a new colormap cell. */
int
-w32_defined_color (FRAME_PTR f, const char *color, XColor *color_def, int alloc)
+w32_defined_color (struct frame *f, const char *color, XColor *color_def, int alloc)
{
register Lisp_Object tem;
COLORREF w32_color_ref;
ARG says. */
int
-x_decode_color (FRAME_PTR f, Lisp_Object arg, int def)
+x_decode_color (struct frame *f, Lisp_Object arg, int def)
{
XColor cdef;
else if (strcmp (SDATA (arg), "white") == 0)
return WHITE_PIX_DEFAULT (f);
- if ((FRAME_W32_DISPLAY_INFO (f)->n_planes * FRAME_W32_DISPLAY_INFO (f)->n_cbits) == 1)
+ if ((FRAME_DISPLAY_INFO (f)->n_planes * FRAME_DISPLAY_INFO (f)->n_cbits) == 1)
return def;
/* w32_defined_color is responsible for coping with failures
void
-x_set_cursor_type (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
set_frame_cursor_types (f, arg);
-
- /* Make sure the cursor gets redrawn. */
- cursor_type_changed = 1;
}
-\f
+
void
x_set_icon_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
do_pending_window_change (0);
}
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
}
nlines = 0;
/* Make sure we redisplay all windows in this frame. */
- ++windows_or_buffers_changed;
+ windows_or_buffers_changed = 23;
delta = nlines - FRAME_TOOL_BAR_LINES (f);
FRAME_TOOL_BAR_LINES (f) = nlines;
resize_frame_windows (f, FRAME_LINES (f), 0);
- adjust_glyphs (f);
+ adjust_frame_glyphs (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
/* If we're switching from explicit to implicit, we had better
update the mode lines and thereby update the title. */
if (f->explicit_name && NILP (name))
- update_mode_lines = 1;
+ update_mode_lines = 25;
f->explicit_name = ! NILP (name);
}
{
/* Check for no change needed in this very common case
before we do any consing. */
- if (!strcmp (FRAME_W32_DISPLAY_INFO (f)->w32_id_name,
+ if (!strcmp (FRAME_DISPLAY_INFO (f)->w32_id_name,
SDATA (f->name)))
return;
- name = build_string (FRAME_W32_DISPLAY_INFO (f)->w32_id_name);
+ name = build_string (FRAME_DISPLAY_INFO (f)->w32_id_name);
}
else
CHECK_STRING (name);
if (FRAME_W32_WINDOW (f))
{
- if (STRING_MULTIBYTE (name))
- name = ENCODE_SYSTEM (name);
-
block_input ();
- SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
+ GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f),
+ GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
unblock_input ();
}
}
specified a name for the frame; the name will override any set by the
redisplay code. */
void
-x_explicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 1);
}
name; names set this way will never override names set by the user's
lisp code. */
void
-x_implicitly_set_name (FRAME_PTR f, Lisp_Object arg, Lisp_Object oldval)
+x_implicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
{
x_set_name (f, arg, 0);
}
if (EQ (name, f->title))
return;
- update_mode_lines = 1;
+ update_mode_lines = 26;
fset_title (f, name);
if (FRAME_W32_WINDOW (f))
{
- if (STRING_MULTIBYTE (name))
- name = ENCODE_SYSTEM (name);
-
block_input ();
- SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
+ GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f),
+ GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
unblock_input ();
}
}
static HWND
w32_createscrollbar (struct frame *f, struct scroll_bar * bar)
{
- return (CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
- /* Position and size of scroll bar. */
- XINT (bar->left) + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
- XINT (bar->top),
- XINT (bar->width) - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- XINT (bar->height),
- FRAME_W32_WINDOW (f),
- NULL,
- hinst,
- NULL));
+ return CreateWindow ("SCROLLBAR", "", SBS_VERT | WS_CHILD | WS_VISIBLE,
+ /* Position and size of scroll bar. */
+ XINT (bar->left), XINT (bar->top),
+ XINT (bar->width), XINT (bar->height),
+ FRAME_W32_WINDOW (f), NULL, hinst, NULL);
}
static void
HIMC context;
struct window *w;
+ /* Implementation note: The code below does something that
+ one shouldn't do: it accesses the window object from a
+ separate thread, while the main (a.k.a. "Lisp") thread
+ runs and can legitimately delete and even GC it. That is
+ why we are extra careful not to futz with a window that
+ is different from the one recorded when the system caret
+ coordinates were last modified. That is also why we are
+ careful not to move the IME window if the window
+ described by W was deleted, as indicated by its buffer
+ field being reset to nil. */
f = x_window_to_frame (dpyinfo, hwnd);
+ if (!(f && FRAME_LIVE_P (f)))
+ break;
w = XWINDOW (FRAME_SELECTED_WINDOW (f));
+ /* Punt if someone changed the frame's selected window
+ behind our back. */
+ if (w != w32_system_caret_window)
+ break;
form.dwStyle = CFS_RECT;
form.ptCurrentPos.x = w32_system_caret_x;
form.rcArea.left = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, 0);
form.rcArea.top = (WINDOW_TOP_EDGE_Y (w)
- + WINDOW_HEADER_LINE_HEIGHT (w));
+ + w32_system_caret_hdr_height);
form.rcArea.right = (WINDOW_BOX_RIGHT_EDGE_X (w)
- WINDOW_RIGHT_MARGIN_WIDTH (w)
- WINDOW_RIGHT_FRINGE_WIDTH (w));
form.rcArea.bottom = (WINDOW_BOTTOM_EDGE_Y (w)
- - WINDOW_MODE_LINE_HEIGHT (w));
+ - w32_system_caret_mode_height);
+
+ /* Punt if the window was deleted behind our back. */
+ if (!BUFFERP (w->contents))
+ break;
context = get_ime_context_fn (hwnd);
/* Don't restrict the sizing of tip frames. */
if (hwnd == tip_window)
return 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);
+ if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
+ return 0;
+
{
WINDOWPLACEMENT wp;
LPWINDOWPOS lppos = (WINDOWPOS *) lParam;
for the window manager, so GC relocation won't bother it.
Elsewhere we specify the window name for the window manager. */
-
- {
- char *str = SSDATA (Vx_resource_name);
- f->namebuf = xmalloc (strlen (str) + 1);
- strcpy (f->namebuf, str);
- }
+ f->namebuf = xstrdup (SSDATA (Vx_resource_name));
my_create_window (f);
block_input ();
- if (! EQ (icon_x, Qunbound))
- x_wm_set_icon_position (f, XINT (icon_x), XINT (icon_y));
-
#if 0 /* TODO */
/* Start up iconic or window? */
x_wm_set_window_state
if (NILP (Fmemq (frame, Vframe_list)))
{
#ifdef GLYPH_DEBUG
- struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+ struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
#endif
x_free_frame_resources (f);
return Qnil;
}
+static void
+do_unwind_create_frame (Lisp_Object frame)
+{
+ unwind_create_frame (frame);
+}
+
static void
x_default_font_parameter (struct frame *f, Lisp_Object parms)
{
- struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (f);
+ struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f);
Lisp_Object font_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL,
RES_TYPE_STRING);
Lisp_Object font;
if (! STRINGP (f->icon_name))
fset_icon_name (f, Qnil);
-/* FRAME_W32_DISPLAY_INFO (f) = dpyinfo; */
+/* FRAME_DISPLAY_INFO (f) = dpyinfo; */
- /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */
- record_unwind_protect (unwind_create_frame, frame);
+ /* With FRAME_DISPLAY_INFO set up, this unwind-protect is safe. */
+ record_unwind_protect (do_unwind_create_frame, frame);
#ifdef GLYPH_DEBUG
image_cache_refcount =
FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0;
}
else
{
- f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
+ f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
f->output_data.w32->explicit_parent = 0;
}
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
"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;
+ f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
f->output_data.w32->text_cursor = w32_load_cursor (IDC_IBEAM);
f->output_data.w32->nontext_cursor = w32_load_cursor (IDC_ARROW);
/* Now consider the frame official. */
f->terminal->reference_count++;
- FRAME_W32_DISPLAY_INFO (f)->reference_count++;
+ FRAME_DISPLAY_INFO (f)->reference_count++;
Vframe_list = Fcons (frame, Vframe_list);
/* We need to do this after creating the window, so that the
Lisp_Object
x_get_focus_frame (struct frame *frame)
{
- struct w32_display_info *dpyinfo = FRAME_W32_DISPLAY_INFO (frame);
+ struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (frame);
Lisp_Object xfocus;
if (! dpyinfo->w32_focus_frame)
return Qnil;
return xfocus;
}
-DEFUN ("x-focus-frame", Fx_focus_frame, Sx_focus_frame, 1, 1, 0,
- doc: /* Give FRAME input focus, raising to foreground if necessary. */)
- (Lisp_Object frame)
-{
- x_focus_on_frame (check_x_frame (frame));
- return Qnil;
-}
-
-\f
DEFUN ("xw-color-defined-p", Fxw_color_defined_p, Sxw_color_defined_p, 1, 2, 0,
doc: /* Internal function called by `color-defined-p', which see.
\(Note that the Nextstep version of this function ignores FRAME.) */)
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
if (w32_defined_color (f, SDATA (color), &foo, 0))
- return list3 (make_number ((GetRValue (foo.pixel) << 8)
- | GetRValue (foo.pixel)),
- make_number ((GetGValue (foo.pixel) << 8)
- | GetGValue (foo.pixel)),
- make_number ((GetBValue (foo.pixel) << 8)
- | GetBValue (foo.pixel)));
+ return list3i ((GetRValue (foo.pixel) << 8) | GetRValue (foo.pixel),
+ (GetGValue (foo.pixel) << 8) | GetGValue (foo.pixel),
+ (GetBValue (foo.pixel) << 8) | GetBValue (foo.pixel));
else
return Qnil;
}
doc: /* Return 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. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel width for all
+physical monitors associated with DISPLAY. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object display)
{
struct w32_display_info *dpyinfo = check_x_display_info (display);
doc: /* Return 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. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the pixel height for all
+physical monitors associated with DISPLAY. To get information for
+each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object display)
{
struct w32_display_info *dpyinfo = check_x_display_info (display);
If omitted or nil, that stands for the selected frame's display. */)
(Lisp_Object display)
{
- return Fcons (make_number (w32_major_version),
- Fcons (make_number (w32_minor_version),
- Fcons (make_number (w32_build_number), Qnil)));
+ return list3i (w32_major_version, w32_minor_version, w32_build_number);
}
DEFUN ("x-display-screens", Fx_display_screens, Sx_display_screens, 0, 1, 0,
doc: /* Return 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. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the height in millimeters for
+all physical monitors associated with DISPLAY. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object display)
{
struct w32_display_info *dpyinfo = check_x_display_info (display);
HDC hdc;
- int cap;
-
- hdc = GetDC (dpyinfo->root_window);
-
- cap = GetDeviceCaps (hdc, VERTSIZE);
+ double mm_per_pixel;
- ReleaseDC (dpyinfo->root_window, hdc);
+ hdc = GetDC (NULL);
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE)
+ / GetDeviceCaps (hdc, VERTRES));
+ ReleaseDC (NULL, hdc);
- return make_number (cap);
+ return make_number (x_display_pixel_height (dpyinfo) * mm_per_pixel + 0.5);
}
DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0,
doc: /* Return 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. */)
+If omitted or nil, that stands for the selected frame's display.
+
+On \"multi-monitor\" setups this refers to the width in millimeters for
+all physical monitors associated with TERMINAL. To get information
+for each physical monitor, use `display-monitor-attributes-list'. */)
(Lisp_Object display)
{
struct w32_display_info *dpyinfo = check_x_display_info (display);
-
HDC hdc;
- int cap;
-
- hdc = GetDC (dpyinfo->root_window);
-
- cap = GetDeviceCaps (hdc, HORZSIZE);
+ double mm_per_pixel;
- ReleaseDC (dpyinfo->root_window, hdc);
+ hdc = GetDC (NULL);
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE)
+ / GetDeviceCaps (hdc, HORZRES));
+ ReleaseDC (NULL, hdc);
- return make_number (cap);
+ return make_number (x_display_pixel_width (dpyinfo) * mm_per_pixel + 0.5);
}
DEFUN ("x-display-backing-store", Fx_display_backing_store,
return Qnil;
}
+static BOOL CALLBACK
+w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData)
+{
+ Lisp_Object *monitor_list = (Lisp_Object *) dwData;
+
+ *monitor_list = Fcons (make_save_ptr (monitor), *monitor_list);
+
+ return TRUE;
+}
+
+static Lisp_Object
+w32_display_monitor_attributes_list (void)
+{
+ Lisp_Object attributes_list = Qnil, primary_monitor_attributes = Qnil;
+ Lisp_Object monitor_list = Qnil, monitor_frames, rest, frame;
+ int i, n_monitors;
+ HMONITOR *monitors;
+ struct gcpro gcpro1, gcpro2, gcpro3;
+
+ if (!(enum_display_monitors_fn && get_monitor_info_fn
+ && monitor_from_window_fn))
+ return Qnil;
+
+ if (!enum_display_monitors_fn (NULL, NULL, w32_monitor_enum,
+ (LPARAM) &monitor_list)
+ || NILP (monitor_list))
+ return Qnil;
+
+ n_monitors = 0;
+ for (rest = monitor_list; CONSP (rest); rest = XCDR (rest))
+ n_monitors++;
+
+ monitors = xmalloc (n_monitors * sizeof (*monitors));
+ for (i = 0; i < n_monitors; i++)
+ {
+ monitors[i] = XSAVE_POINTER (XCAR (monitor_list), 0);
+ monitor_list = XCDR (monitor_list);
+ }
+
+ monitor_frames = Fmake_vector (make_number (n_monitors), Qnil);
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
+ {
+ HMONITOR monitor =
+ monitor_from_window_fn (FRAME_W32_WINDOW (f),
+ MONITOR_DEFAULT_TO_NEAREST);
+
+ for (i = 0; i < n_monitors; i++)
+ if (monitors[i] == monitor)
+ break;
+
+ if (i < n_monitors)
+ ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i)));
+ }
+ }
+
+ GCPRO3 (attributes_list, primary_monitor_attributes, monitor_frames);
+
+ for (i = 0; i < n_monitors; i++)
+ {
+ Lisp_Object geometry, workarea, name, attributes = Qnil;
+ HDC hdc;
+ int width_mm, height_mm;
+ struct MONITOR_INFO_EX mi;
+
+ mi.cbSize = sizeof (mi);
+ if (!get_monitor_info_fn (monitors[i], (struct MONITOR_INFO *) &mi))
+ continue;
+
+ hdc = CreateDCA ("DISPLAY", mi.szDevice, NULL, NULL);
+ if (hdc == NULL)
+ continue;
+ width_mm = GetDeviceCaps (hdc, HORZSIZE);
+ height_mm = GetDeviceCaps (hdc, VERTSIZE);
+ DeleteDC (hdc);
+
+ attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)),
+ attributes);
+
+ name = DECODE_SYSTEM (build_unibyte_string (mi.szDevice));
+
+ attributes = Fcons (Fcons (Qname, name), attributes);
+
+ attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)),
+ attributes);
+
+ workarea = list4i (mi.rcWork.left, mi.rcWork.top,
+ mi.rcWork.right - mi.rcWork.left,
+ mi.rcWork.bottom - mi.rcWork.top);
+ attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
+
+ geometry = list4i (mi.rcMonitor.left, mi.rcMonitor.top,
+ mi.rcMonitor.right - mi.rcMonitor.left,
+ mi.rcMonitor.bottom - mi.rcMonitor.top);
+ attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
+
+ if (mi.dwFlags & MONITORINFOF_PRIMARY)
+ primary_monitor_attributes = attributes;
+ else
+ attributes_list = Fcons (attributes, attributes_list);
+ }
+
+ if (!NILP (primary_monitor_attributes))
+ attributes_list = Fcons (primary_monitor_attributes, attributes_list);
+
+ UNGCPRO;
+
+ xfree (monitors);
+
+ return attributes_list;
+}
+
+static Lisp_Object
+w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo)
+{
+ Lisp_Object geometry, workarea, frames, rest, frame, attributes = Qnil;
+ HDC hdc;
+ double mm_per_pixel;
+ int pixel_width, pixel_height, width_mm, height_mm;
+ RECT workarea_rect;
+
+ /* Fallback: treat (possibly) multiple physical monitors as if they
+ formed a single monitor as a whole. This should provide a
+ consistent result at least on single monitor environments. */
+ attributes = Fcons (Fcons (Qname, build_string ("combined screen")),
+ attributes);
+
+ frames = Qnil;
+ FOR_EACH_FRAME (rest, frame)
+ {
+ struct frame *f = XFRAME (frame);
+
+ if (FRAME_W32_P (f) && !EQ (frame, tip_frame))
+ frames = Fcons (frame, frames);
+ }
+ attributes = Fcons (Fcons (Qframes, frames), attributes);
+
+ pixel_width = x_display_pixel_width (dpyinfo);
+ pixel_height = x_display_pixel_height (dpyinfo);
+
+ hdc = GetDC (NULL);
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE)
+ / GetDeviceCaps (hdc, HORZRES));
+ width_mm = pixel_width * mm_per_pixel + 0.5;
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE)
+ / GetDeviceCaps (hdc, VERTRES));
+ height_mm = pixel_height * mm_per_pixel + 0.5;
+ ReleaseDC (NULL, hdc);
+ attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)),
+ attributes);
+
+ /* GetSystemMetrics below may return 0 for Windows 95 or NT 4.0, but
+ we don't care. */
+ geometry = list4i (GetSystemMetrics (SM_XVIRTUALSCREEN),
+ GetSystemMetrics (SM_YVIRTUALSCREEN),
+ pixel_width, pixel_height);
+ if (SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0))
+ workarea = list4i (workarea_rect.left, workarea_rect.top,
+ workarea_rect.right - workarea_rect.left,
+ workarea_rect.bottom - workarea_rect.top);
+ else
+ workarea = geometry;
+ attributes = Fcons (Fcons (Qworkarea, workarea), attributes);
+
+ attributes = Fcons (Fcons (Qgeometry, geometry), attributes);
+
+ return list1 (attributes);
+}
+
+DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list,
+ Sw32_display_monitor_attributes_list,
+ 0, 1, 0,
+ doc: /* Return a list of physical monitor attributes on the W32 display 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.
+
+Internal use only, use `display-monitor-attributes-list' instead. */)
+ (Lisp_Object display)
+{
+ struct w32_display_info *dpyinfo = check_x_display_info (display);
+ Lisp_Object attributes_list;
+
+ block_input ();
+ attributes_list = w32_display_monitor_attributes_list ();
+ if (NILP (attributes_list))
+ attributes_list = w32_display_monitor_attributes_list_fallback (dpyinfo);
+ unblock_input ();
+
+ return attributes_list;
+}
+
DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0,
doc: /* Set the sound generated when the bell is rung.
SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent
return sound;
}
-\f
-int
-x_pixel_width (register struct frame *f)
-{
- return FRAME_PIXEL_WIDTH (f);
-}
-
-int
-x_pixel_height (register struct frame *f)
-{
- return FRAME_PIXEL_HEIGHT (f);
-}
-
int
x_screen_planes (register struct frame *f)
{
- return FRAME_W32_DISPLAY_INFO (f)->n_planes;
+ return FRAME_DISPLAY_INFO (f)->n_planes;
}
\f
/* Return the display structure for the display named NAME.
struct w32_display_info *
x_display_info_for_name (Lisp_Object name)
{
- Lisp_Object names;
struct w32_display_info *dpyinfo;
CHECK_STRING (name);
- for (dpyinfo = &one_w32_display_info, names = w32_display_name_list;
- dpyinfo && !NILP (w32_display_name_list);
- dpyinfo = dpyinfo->next, names = XCDR (names))
- {
- Lisp_Object tem;
- tem = Fstring_equal (XCAR (XCAR (names)), name);
- if (!NILP (tem))
- return dpyinfo;
- }
+ for (dpyinfo = &one_w32_display_info; dpyinfo; dpyinfo = dpyinfo->next)
+ if (!NILP (Fstring_equal (XCAR (dpyinfo->name_list_element), name)))
+ return dpyinfo;
/* Use this general default value to start with. */
Vx_resource_name = Vinvocation_name;
if (dpyinfo == 0)
error ("Cannot connect to server %s", SDATA (name));
- w32_in_use = 1;
XSETFASTINT (Vwindow_system_version, w32_major_version);
return dpyinfo;
/* If initialization has already been done, return now to avoid
overwriting critical parts of one_w32_display_info. */
- if (w32_in_use)
+ if (window_system_available (NULL))
return Qnil;
if (! NILP (xrm_string))
CHECK_STRING (xrm_string);
-#if 0
- if (! EQ (Vwindow_system, intern ("w32")))
- error ("Not using Microsoft Windows");
-#endif
-
/* Allow color mapping to be defined externally; first look in user's
HOME directory, then in Emacs etc dir for a file called rgb.txt. */
{
error ("Cannot connect to server %s", SDATA (display));
}
- w32_in_use = 1;
-
XSETFASTINT (Vwindow_system_version, w32_major_version);
return Qnil;
}
doc: /* Return the list of display names that Emacs has connections to. */)
(void)
{
- Lisp_Object tail, result;
+ Lisp_Object result = Qnil;
+ struct w32_display_info *wdi;
- result = Qnil;
- for (tail = w32_display_name_list; CONSP (tail); tail = XCDR (tail))
- result = Fcons (XCAR (XCAR (tail)), result);
+ for (wdi = x_display_list; wdi; wdi = wdi->next)
+ result = Fcons (XCAR (wdi->name_list_element), result);
return result;
}
(Lisp_Object prop, Lisp_Object value, Lisp_Object frame,
Lisp_Object type, Lisp_Object format, Lisp_Object outer_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
CHECK_STRING (prop);
FRAME nil or omitted means use the selected frame. Value is PROP. */)
(Lisp_Object prop, Lisp_Object frame)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
CHECK_STRING (prop);
(Lisp_Object prop, Lisp_Object frame, Lisp_Object type,
Lisp_Object source, Lisp_Object delete_p, Lisp_Object vector_ret_p)
{
- struct frame *f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
Atom prop_atom;
int rc;
Lisp_Object prop_value = Qnil;
f = SELECTED_FRAME ();
if (!FRAME_W32_P (f))
- return;
+ {
+ unblock_input ();
+ return;
+ }
w32_show_hourglass (f);
unblock_input ();
Lisp_Object last_show_tip_args;
-static Lisp_Object
+static void
unwind_create_tip_frame (Lisp_Object frame)
{
Lisp_Object deleted;
tip_window = NULL;
tip_frame = Qnil;
}
-
- return deleted;
}
Lisp_Object buffer;
struct buffer *old_buffer;
- check_w32 ();
-
/* Use this general default value to start with until we know if
this frame has a specified name. */
Vx_resource_name = Vinvocation_name;
dpyinfo_refcount = dpyinfo->reference_count;
#endif /* GLYPH_DEBUG */
FRAME_KBOARD (f) = kb;
- f->output_data.w32->parent_desc = FRAME_W32_DISPLAY_INFO (f)->root_window;
+ f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
f->output_data.w32->explicit_parent = 0;
/* Set the name; the functions to which we pass f expect the name to
specbind (Qx_resource_name, name);
}
- f->resx = dpyinfo->resx;
- f->resy = dpyinfo->resy;
-
if (uniscribe_available)
register_font_driver (&uniscribe_font_driver, f);
register_font_driver (&w32font_driver, f);
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;
+ f->output_data.w32->parent_desc = FRAME_DISPLAY_INFO (f)->root_window;
window_prompting = x_figure_window_size (f, parms, 0);
/* Now that the frame is official, it counts as a reference to
its display. */
- FRAME_W32_DISPLAY_INFO (f)->reference_count++;
+ FRAME_DISPLAY_INFO (f)->reference_count++;
f->terminal->reference_count++;
/* It is now ok to make the frame official even if we get an error
/* Default min and max values. */
min_x = 0;
min_y = 0;
- max_x = x_display_pixel_width (FRAME_W32_DISPLAY_INFO (f));
- max_y = x_display_pixel_height (FRAME_W32_DISPLAY_INFO (f));
+ max_x = x_display_pixel_width (FRAME_DISPLAY_INFO (f));
+ max_y = x_display_pixel_height (FRAME_DISPLAY_INFO (f));
block_input ();
GetCursorPos (&pt);
GCPRO4 (string, parms, frame, timeout);
CHECK_STRING (string);
- f = check_x_frame (frame);
+ f = decode_window_system_frame (frame);
if (NILP (timeout))
timeout = make_number (5);
else
/* 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, string);
+ frame = x_create_tip_frame (FRAME_DISPLAY_INFO (f), parms, string);
f = XFRAME (frame);
/* Set up the frame's root window. */
w = XWINDOW (FRAME_ROOT_WINDOW (f));
- wset_left_col (w, make_number (0));
- wset_top_line (w, make_number (0));
+ w->left_col = 0;
+ w->top_line = 0;
if (CONSP (Vx_max_tooltip_size)
&& INTEGERP (XCAR (Vx_max_tooltip_size))
&& INTEGERP (XCDR (Vx_max_tooltip_size))
&& XINT (XCDR (Vx_max_tooltip_size)) > 0)
{
- wset_total_cols (w, XCAR (Vx_max_tooltip_size));
- wset_total_lines (w, XCDR (Vx_max_tooltip_size));
+ w->total_cols = XFASTINT (XCAR (Vx_max_tooltip_size));
+ w->total_lines = XFASTINT (XCDR (Vx_max_tooltip_size));
}
else
{
- wset_total_cols (w, make_number (80));
- wset_total_lines (w, make_number (40));
+ w->total_cols = 80;
+ w->total_lines = 40;
}
- FRAME_TOTAL_COLS (f) = XINT (w->total_cols);
- adjust_glyphs (f);
+ FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
+ adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
/* Display the tooltip text in a temporary buffer. */
old_buffer = current_buffer;
- set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->buffer));
+ set_buffer_internal_1 (XBUFFER (XWINDOW (FRAME_ROOT_WINDOW (f))->contents));
bset_truncate_lines (current_buffer, Qnil);
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
int row_width;
/* Stop at the first empty row at the end. */
- if (!row->enabled_p || !row->displays_text_p)
+ if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
break;
/* Let the row go over the full width of the frame. */
/* w->total_cols and FRAME_TOTAL_COLS want the width in columns,
not in pixels. */
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
- wset_total_cols (w, make_number (width));
+ w->total_cols = width;
FRAME_TOTAL_COLS (f) = width;
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
struct glyph *last;
int row_width;
- if (!row->enabled_p || !row->displays_text_p)
+ if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
break;
row->full_width_p = 1;
row_width = row->pixel_width;
#define FILE_NAME_COMBO_BOX cmb13
#define FILE_NAME_LIST lst1
-#ifdef NTGUI_UNICODE
-#define GUISTR(x) (L ## x)
-typedef wchar_t guichar_t;
-#else /* !NTGUI_UNICODE */
-#define GUISTR(x) x
-typedef char guichar_t;
-#endif /* NTGUI_UNICODE */
-
/* Callback for altering the behavior of the Open File dialog.
Makes the Filename text field contain "Current Directory" and be
read-only when "Directories" is selected in the filter. This
{
if (msg == WM_NOTIFY)
{
+ OFNOTIFYW * notify_w = (OFNOTIFYW *)lParam;
+ OFNOTIFYA * notify_a = (OFNOTIFYA *)lParam;
+ int dropdown_changed;
+ int dir_index;
#ifdef NTGUI_UNICODE
- OFNOTIFYW * notify = (OFNOTIFYW *)lParam;
+ int use_unicode = 1;
#else /* !NTGUI_UNICODE */
- OFNOTIFYA * notify = (OFNOTIFYA *)lParam;
+ int use_unicode = w32_unicode_filenames;
#endif /* NTGUI_UNICODE */
+
/* Detect when the Filter dropdown is changed. */
- if (notify->hdr.code == CDN_TYPECHANGE
- || notify->hdr.code == CDN_INITDONE)
+ if (use_unicode)
+ dropdown_changed =
+ notify_w->hdr.code == CDN_TYPECHANGE
+ || notify_w->hdr.code == CDN_INITDONE;
+ else
+ dropdown_changed =
+ notify_a->hdr.code == CDN_TYPECHANGE
+ || notify_a->hdr.code == CDN_INITDONE;
+ if (dropdown_changed)
{
HWND dialog = GetParent (hwnd);
HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD);
HWND list = GetDlgItem (dialog, FILE_NAME_LIST);
+ int hdr_code;
/* At least on Windows 7, the above attempt to get the window handle
to the File Name Text Field fails. The following code does the
}
/* Directories is in index 2. */
- if (notify->lpOFN->nFilterIndex == 2)
+ if (use_unicode)
{
- CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD,
- GUISTR ("Current Directory"));
+ dir_index = notify_w->lpOFN->nFilterIndex;
+ hdr_code = notify_w->hdr.code;
+ }
+ else
+ {
+ dir_index = notify_a->lpOFN->nFilterIndex;
+ hdr_code = notify_a->hdr.code;
+ }
+ if (dir_index == 2)
+ {
+ if (use_unicode)
+ SendMessageW (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
+ (LPARAM)L"Current Directory");
+ else
+ SendMessageA (dialog, CDM_SETCONTROLTEXT, FILE_NAME_TEXT_FIELD,
+ (LPARAM)"Current Directory");
EnableWindow (edit_control, FALSE);
/* Note that at least on Windows 7, the above call to EnableWindow
disables the window that would ordinarily have focus. If we
no man's land and the user will be unable to tab through the
dialog box (pressing tab will only result in a beep).
Avoid that problem by setting focus to the list here. */
- if (notify->hdr.code == CDN_INITDONE)
+ if (hdr_code == CDN_INITDONE)
SetFocus (list);
}
else
{
/* Don't override default filename on init done. */
- if (notify->hdr.code == CDN_TYPECHANGE)
- CommDlg_OpenSave_SetControlText (dialog,
- FILE_NAME_TEXT_FIELD,
- GUISTR (""));
+ if (hdr_code == CDN_TYPECHANGE)
+ {
+ if (use_unicode)
+ SendMessageW (dialog, CDM_SETCONTROLTEXT,
+ FILE_NAME_TEXT_FIELD, (LPARAM)L"");
+ else
+ SendMessageA (dialog, CDM_SETCONTROLTEXT,
+ FILE_NAME_TEXT_FIELD, (LPARAM)"");
+ }
EnableWindow (edit_control, TRUE);
}
}
(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 */
- static const guichar_t filter[] =
- GUISTR ("All Files (*.*)\0*.*\0Directories\0*|*\0");
+ static const wchar_t filter_w[] = L"All Files (*.*)\0*.*\0Directories\0*|*\0";
+ static const char filter_a[] = "All Files (*.*)\0*.*\0Directories\0*|*\0";
Lisp_Object filename = default_filename;
struct frame *f = SELECTED_FRAME ();
enough struct for the new dialog to trick GetOpenFileName into
giving us the new dialogs on newer versions of Windows. */
struct {
-#ifdef NTGUI_UNICODE
OPENFILENAMEW details;
-#else /* !NTGUI_UNICODE */
- OPENFILENAMEA details;
-#endif /* NTGUI_UNICODE */
-
#if _WIN32_WINNT < 0x500 /* < win2k */
PVOID pvReserved;
DWORD dwReserved;
DWORD FlagsEx;
#endif /* < win2k */
- } new_file_details;
+ } new_file_details_w;
#ifdef NTGUI_UNICODE
- wchar_t filename_buf[32*1024 + 1]; // NT kernel maximum
- OPENFILENAMEW * file_details = &new_file_details.details;
+ wchar_t filename_buf_w[32*1024 + 1]; // NT kernel maximum
+ OPENFILENAMEW * file_details_w = &new_file_details_w.details;
+ int use_unicode = 1;
#else /* not NTGUI_UNICODE */
- char filename_buf[MAX_PATH + 1];
- OPENFILENAMEA * file_details = &new_file_details.details;
+ struct {
+ OPENFILENAMEA details;
+#if _WIN32_WINNT < 0x500 /* < win2k */
+ PVOID pvReserved;
+ DWORD dwReserved;
+ DWORD FlagsEx;
+#endif /* < win2k */
+ } new_file_details_a;
+ wchar_t filename_buf_w[MAX_PATH + 1], dir_w[MAX_PATH];
+ char filename_buf_a[MAX_PATH + 1], dir_a[MAX_PATH];
+ OPENFILENAMEW * file_details_w = &new_file_details_w.details;
+ OPENFILENAMEA * file_details_a = &new_file_details_a.details;
+ int use_unicode = w32_unicode_filenames;
+ wchar_t *prompt_w;
+ char *prompt_a;
+ int len;
+ char fname_ret[MAX_UTF8_PATH];
#endif /* NTGUI_UNICODE */
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6;
to_unicode (prompt, &prompt);
to_unicode (dir, &dir);
to_unicode (filename, &filename);
+ if (SBYTES (filename) + 1 > sizeof (filename_buf_w))
+ report_file_error ("filename too long", default_filename);
+
+ memcpy (filename_buf_w, SDATA (filename), SBYTES (filename) + 1);
#else /* !NTGUI_UNICODE */
prompt = ENCODE_FILE (prompt);
dir = ENCODE_FILE (dir);
unixtodos_filename (SDATA (dir));
filename = Fcopy_sequence (filename);
unixtodos_filename (SDATA (filename));
+ if (SBYTES (filename) >= MAX_UTF8_PATH)
+ report_file_error ("filename too long", default_filename);
+ if (w32_unicode_filenames)
+ {
+ filename_to_utf16 (SSDATA (dir), dir_w);
+ if (filename_to_utf16 (SSDATA (filename), filename_buf_w) != 0)
+ {
+ /* filename_to_utf16 sets errno to ENOENT when the file
+ name is too long or cannot be converted to UTF-16. */
+ if (errno == ENOENT && filename_buf_w[MAX_PATH - 1] != 0)
+ report_file_error ("filename too long", default_filename);
+ }
+ len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+ SSDATA (prompt), -1, NULL, 0);
+ prompt_w = alloca (len * sizeof (wchar_t));
+ MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+ SSDATA (prompt), -1, prompt_w, len);
+ }
+ else
+ {
+ filename_to_ansi (SSDATA (dir), dir_a);
+ if (filename_to_ansi (SSDATA (filename), filename_buf_a) != '\0')
+ {
+ /* filename_to_ansi sets errno to ENOENT when the file
+ name is too long or cannot be converted to UTF-16. */
+ if (errno == ENOENT && filename_buf_a[MAX_PATH - 1] != 0)
+ report_file_error ("filename too long", default_filename);
+ }
+ len = MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+ SSDATA (prompt), -1, NULL, 0);
+ prompt_w = alloca (len * sizeof (wchar_t));
+ MultiByteToWideChar (CP_UTF8, MB_ERR_INVALID_CHARS,
+ SSDATA (prompt), -1, prompt_w, len);
+ len = WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, NULL, 0, NULL, NULL);
+ prompt_a = alloca (len);
+ WideCharToMultiByte (CP_ACP, 0, prompt_w, -1, prompt_a, len, NULL, NULL);
+ }
#endif /* NTGUI_UNICODE */
/* Fill in the structure for the call to GetOpenFileName below.
builds, we tell the OS we're using an old version of the
structure if the OS isn't new enough to support the newer
version. */
- memset (&new_file_details, 0, sizeof (new_file_details));
-
- if (w32_major_version > 4 && w32_major_version < 95)
- file_details->lStructSize = sizeof (new_file_details);
+ if (use_unicode)
+ {
+ memset (&new_file_details_w, 0, sizeof (new_file_details_w));
+ if (w32_major_version > 4 && w32_major_version < 95)
+ file_details_w->lStructSize = sizeof (new_file_details_w);
+ else
+ file_details_w->lStructSize = sizeof (*file_details_w);
+ /* Set up the inout parameter for the selected file name. */
+ file_details_w->lpstrFile = filename_buf_w;
+ file_details_w->nMaxFile =
+ sizeof (filename_buf_w) / sizeof (*filename_buf_w);
+ file_details_w->hwndOwner = FRAME_W32_WINDOW (f);
+ /* Undocumented Bug in Common File Dialog:
+ If a filter is not specified, shell links are not resolved. */
+ file_details_w->lpstrFilter = filter_w;
+#ifdef NTGUI_UNICODE
+ file_details_w->lpstrInitialDir = (wchar_t*) SDATA (dir);
+ file_details->lpstrTitle = (guichar_t*) SDATA (prompt);
+#else
+ file_details_w->lpstrInitialDir = dir_w;
+ file_details_w->lpstrTitle = prompt_w;
+#endif
+ file_details_w->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
+ file_details_w->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+ | OFN_EXPLORER | OFN_ENABLEHOOK);
+ if (!NILP (mustmatch))
+ {
+ /* Require that the path to the parent directory exists. */
+ file_details_w->Flags |= OFN_PATHMUSTEXIST;
+ /* If we are looking for a file, require that it exists. */
+ if (NILP (only_dir_p))
+ file_details_w->Flags |= OFN_FILEMUSTEXIST;
+ }
+ }
else
- file_details->lStructSize = sizeof (*file_details);
-
- /* Set up the inout parameter for the selected file name. */
- if (SBYTES (filename) + 1 > sizeof (filename_buf))
- report_file_error ("filename too long", default_filename);
-
- memcpy (filename_buf, SDATA (filename), SBYTES (filename) + 1);
- file_details->lpstrFile = filename_buf;
- file_details->nMaxFile = sizeof (filename_buf) / sizeof (*filename_buf);
-
- file_details->hwndOwner = FRAME_W32_WINDOW (f);
- /* Undocumented Bug in Common File Dialog:
- If a filter is not specified, shell links are not resolved. */
- file_details->lpstrFilter = filter;
- file_details->lpstrInitialDir = (guichar_t*) SDATA (dir);
- file_details->lpstrTitle = (guichar_t*) SDATA (prompt);
- file_details->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
- file_details->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
- | OFN_EXPLORER | OFN_ENABLEHOOK);
-
- if (!NILP (mustmatch))
{
- /* Require that the path to the parent directory exists. */
- file_details->Flags |= OFN_PATHMUSTEXIST;
- /* If we are looking for a file, require that it exists. */
- if (NILP (only_dir_p))
- file_details->Flags |= OFN_FILEMUSTEXIST;
+ memset (&new_file_details_a, 0, sizeof (new_file_details_a));
+ if (w32_major_version > 4 && w32_major_version < 95)
+ file_details_a->lStructSize = sizeof (new_file_details_a);
+ else
+ file_details_a->lStructSize = sizeof (*file_details_a);
+ file_details_a->lpstrFile = filename_buf_a;
+ file_details_a->nMaxFile =
+ sizeof (filename_buf_a) / sizeof (*filename_buf_a);
+ file_details_a->hwndOwner = FRAME_W32_WINDOW (f);
+ file_details_a->lpstrFilter = filter_a;
+ file_details_a->lpstrInitialDir = dir_a;
+ file_details_a->lpstrTitle = prompt_a;
+ file_details_a->nFilterIndex = NILP (only_dir_p) ? 1 : 2;
+ file_details_a->Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR
+ | OFN_EXPLORER | OFN_ENABLEHOOK);
+ if (!NILP (mustmatch))
+ {
+ /* Require that the path to the parent directory exists. */
+ file_details_a->Flags |= OFN_PATHMUSTEXIST;
+ /* If we are looking for a file, require that it exists. */
+ if (NILP (only_dir_p))
+ file_details_a->Flags |= OFN_FILEMUSTEXIST;
+ }
}
{
/* Prevent redisplay. */
specbind (Qinhibit_redisplay, Qt);
block_input ();
- file_details->lpfnHook = file_dialog_callback;
+ if (use_unicode)
+ {
+ file_details_w->lpfnHook = file_dialog_callback;
-#ifdef NTGUI_UNICODE
- file_opened = GetOpenFileNameW (file_details);
-#else /* !NTGUI_UNICODE */
- file_opened = GetOpenFileNameA (file_details);
-#endif /* NTGUI_UNICODE */
+ file_opened = GetOpenFileNameW (file_details_w);
+ }
+ else
+ {
+ file_details_a->lpfnHook = file_dialog_callback;
+
+ file_opened = GetOpenFileNameA (file_details_a);
+ }
unblock_input ();
unbind_to (count, Qnil);
}
{
/* Get an Emacs string from the value Windows gave us. */
#ifdef NTGUI_UNICODE
- filename = from_unicode (
- make_unibyte_string (
- (char*) filename_buf,
- /* we get one of the two final 0 bytes for free. */
- 1 + sizeof (wchar_t) * wcslen (filename_buf)));
+ filename = from_unicode_buffer (filename_buf_w);
#else /* !NTGUI_UNICODE */
- dostounix_filename (filename_buf, 0);
- filename = DECODE_FILE (build_string (filename_buf));
+ if (use_unicode)
+ filename_from_utf16 (filename_buf_w, fname_ret);
+ else
+ filename_from_ansi (filename_buf_a, fname_ret);
+ dostounix_filename (fname_ret);
+ filename = DECODE_FILE (build_unibyte_string (fname_ret));
#endif /* NTGUI_UNICODE */
#ifdef CYGWIN
/* Strip the dummy filename off the end of the string if we
added it to select a directory. */
- if (file_details->nFilterIndex == 2)
- {
- filename = Ffile_name_directory (filename);
- }
+ if (use_unicode && file_details_w->nFilterIndex == 2
+ || !use_unicode && file_details_a->nFilterIndex == 2)
+ filename = Ffile_name_directory (filename);
}
/* User canceled the dialog without making a selection. */
else if (!CommDlgExtendedError ())
If optional parameter FRAME is not specified, use selected frame. */)
(Lisp_Object command, Lisp_Object frame)
{
- FRAME_PTR f = check_x_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_NUMBER (command);
CHECK_STRING (document);
/* Encode filename, current directory and parameters. */
- current_dir = ENCODE_FILE (BVAR (current_buffer, directory));
- document = ENCODE_FILE (document);
+ current_dir = BVAR (current_buffer, directory);
+
+#ifdef CYGWIN
+ current_dir = Fcygwin_convert_file_name_to_windows (current_dir, Qt);
+ if (STRINGP (document))
+ document = Fcygwin_convert_file_name_to_windows (document, Qt);
+#endif /* CYGWIN */
+
+ current_dir = GUI_ENCODE_FILE (current_dir);
+ if (STRINGP (document))
+ document = GUI_ENCODE_FILE (document);
if (STRINGP (parameters))
- parameters = ENCODE_SYSTEM (parameters);
-
- if ((int) ShellExecute (NULL,
- (STRINGP (operation) ?
- SDATA (operation) : NULL),
- SDATA (document),
- (STRINGP (parameters) ?
- SDATA (parameters) : NULL),
- SDATA (current_dir),
- (INTEGERP (show_flag) ?
- XINT (show_flag) : SW_SHOWDEFAULT))
+ parameters = GUI_ENCODE_SYSTEM (parameters);
+
+ if ((int) GUI_FN (ShellExecute) (NULL,
+ (STRINGP (operation) ?
+ GUI_SDATA (operation) : NULL),
+ GUI_SDATA (document),
+ (STRINGP (parameters) ?
+ GUI_SDATA (parameters) : NULL),
+ GUI_SDATA (current_dir),
+ (INTEGERP (show_flag) ?
+ XINT (show_flag) : SW_SHOWDEFAULT))
> 32)
return Qt;
errstr = w32_strerror (0);
}
\f
+#ifdef WINDOWSNT
DEFUN ("file-system-info", Ffile_system_info, Sfile_system_info, 1, 1, 0,
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
return value;
}
+#endif /* WINDOWSNT */
+
\f
DEFUN ("default-printer-name", Fdefault_printer_name, Sdefault_printer_name,
0, 0, 0, doc: /* Return the name of Windows default printer device. */)
syms_of_w32fns (void)
{
globals_of_w32fns ();
- /* This is zero if not using MS-Windows. */
- w32_in_use = 0;
track_mouse_window = NULL;
w32_visible_system_caret_hwnd = NULL;
DEFSYM (Qcontrol, "control");
DEFSYM (Qshift, "shift");
DEFSYM (Qfont_param, "font-parameter");
+ DEFSYM (Qgeometry, "geometry");
+ DEFSYM (Qworkarea, "workarea");
+ DEFSYM (Qmm_size, "mm-size");
+ DEFSYM (Qframes, "frames");
/* This is the end of symbol initialization. */
defsubr (&Sx_close_connection);
defsubr (&Sx_display_list);
defsubr (&Sx_synchronize);
- defsubr (&Sx_focus_frame);
/* W32 specific functions */
defsubr (&Sw32_define_rgb_color);
defsubr (&Sw32_default_color_map);
+ defsubr (&Sw32_display_monitor_attributes_list);
defsubr (&Sw32_send_sys_command);
defsubr (&Sw32_shell_execute);
defsubr (&Sw32_register_hot_key);
defsubr (&Sw32_window_exists_p);
defsubr (&Sw32_battery_status);
+#ifdef WINDOWSNT
defsubr (&Sfile_system_info);
+#endif
+
defsubr (&Sdefault_printer_name);
defsubr (&Sset_message_beep);
- check_window_system_func = check_w32;
-
hourglass_hwnd = NULL;
defsubr (&Sx_show_tip);
GetProcAddress (user32_lib, "MonitorFromPoint");
get_monitor_info_fn = (GetMonitorInfo_Proc)
GetProcAddress (user32_lib, "GetMonitorInfoA");
+ monitor_from_window_fn = (MonitorFromWindow_Proc)
+ GetProcAddress (user32_lib, "MonitorFromWindow");
+ enum_display_monitors_fn = (EnumDisplayMonitors_Proc)
+ GetProcAddress (user32_lib, "EnumDisplayMonitors");
{
HMODULE imm32_lib = GetModuleHandle ("imm32.dll");
#endif
if (stderr_fd >= 0)
write (stderr_fd, "\r\nBacktrace:\r\n", 14);
+#ifdef CYGWIN
+#define _open open
+#endif
errfile_fd = _open ("emacs_backtrace.txt", O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
if (errfile_fd >= 0)
{
}
}
}
+
+#ifdef NTGUI_UNICODE
+
+Lisp_Object
+ntgui_encode_system (Lisp_Object str)
+{
+ Lisp_Object encoded;
+ to_unicode (str, &encoded);
+ return encoded;
+}
+
+#endif /* NTGUI_UNICODE */