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);
(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;
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
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;
}
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);
}
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
{
/* 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);
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);
}
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
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. */
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;
}
"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 (decode_window_system_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 = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
(Lisp_Object color, Lisp_Object frame)
{
XColor foo;
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_STRING (color);
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);
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);
+ double mm_per_pixel;
- cap = GetDeviceCaps (hdc, VERTSIZE);
+ hdc = GetDC (NULL);
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE)
+ / GetDeviceCaps (hdc, VERTRES));
+ ReleaseDC (NULL, hdc);
- ReleaseDC (dpyinfo->root_window, 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;
+ double mm_per_pixel;
- hdc = GetDC (dpyinfo->root_window);
+ hdc = GetDC (NULL);
+ mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE)
+ / GetDeviceCaps (hdc, HORZRES));
+ ReleaseDC (NULL, hdc);
- cap = GetDeviceCaps (hdc, HORZSIZE);
-
- ReleaseDC (dpyinfo->root_window, 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.
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. */
{
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;
}
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
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);
/* 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. */
}
FRAME_TOTAL_COLS (f) = WINDOW_TOTAL_COLS (w);
- adjust_glyphs (f);
+ adjust_frame_glyphs (f);
w->pseudo_window_p = 1;
/* Display the tooltip text in a temporary buffer. */
width /= WINDOW_FRAME_COLUMN_WIDTH (w);
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);
If optional parameter FRAME is not specified, use selected frame. */)
(Lisp_Object command, Lisp_Object frame)
{
- FRAME_PTR f = decode_window_system_frame (frame);
+ struct frame *f = decode_window_system_frame (frame);
CHECK_NUMBER (command);
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);
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");