From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: YAMAMOTO Mitsuharu Newsgroups: gmane.emacs.devel Subject: Re: x-display-pixel-width/height inconsistency Date: Tue, 02 Jul 2013 10:30:24 +0900 Organization: Faculty of Science, Chiba University Message-ID: References: <5073D6B8-95E4-4012-AA74-106F428379DC@swipnet.se> <8BD4B041-5A3F-4D7C-AFD3-E997E194AA9D@swipnet.se> <02B98FCD-71DB-47EC-B58B-41A2539FF61A@swipnet.se> <83vc6tcqss.fsf@gnu.org> <83haibdipo.fsf@gnu.org> <837gj7co0l.fsf@gnu.org> <8338tvcjlp.fsf@gnu.org> <83wqr7b3h6.fsf@gnu.org> <51D12678.5090806@gmx.at> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Trace: ger.gmane.org 1372728643 21329 80.91.229.3 (2 Jul 2013 01:30:43 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 2 Jul 2013 01:30:43 +0000 (UTC) Cc: emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jul 02 03:30:43 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UtpQY-0002GR-L4 for ged-emacs-devel@m.gmane.org; Tue, 02 Jul 2013 03:30:42 +0200 Original-Received: from localhost ([::1]:43884 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UtpQX-0003fD-TB for ged-emacs-devel@m.gmane.org; Mon, 01 Jul 2013 21:30:42 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:36619) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UtpQQ-0003f2-Vu for emacs-devel@gnu.org; Mon, 01 Jul 2013 21:30:38 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UtpQN-0006rG-Oq for emacs-devel@gnu.org; Mon, 01 Jul 2013 21:30:34 -0400 Original-Received: from mathmail.math.s.chiba-u.ac.jp ([133.82.132.2]:50668) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UtpQM-0006qg-Ov for emacs-devel@gnu.org; Mon, 01 Jul 2013 21:30:31 -0400 Original-Received: from church.math.s.chiba-u.ac.jp (church [133.82.132.36]) by mathmail.math.s.chiba-u.ac.jp (Postfix) with ESMTP id 801F5C055D; Tue, 2 Jul 2013 10:30:24 +0900 (JST) In-Reply-To: <51D12678.5090806@gmx.at> User-Agent: Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.8 (=?ISO-8859-4?Q?Shij=F2?=) APEL/10.6 Emacs/22.3 (sparc-sun-solaris2.8) MULE/5.0 (SAKAKI) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 133.82.132.2 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:161436 Archived-At: >>>>> On Mon, 01 Jul 2013 08:49:28 +0200, martin rudalics said: >>> By the way, has anyone tried the patch for W32 on a real >>> multi-monitor setup? I'd like to know the results for the >>> following expressions: >> >>> (display-monitor-attributes-list) >> >>> (list (display-pixel-width) (display-pixel-height)) >> >> There was a silly mistake in the previous patch. Please try the >> following one instead. > Sorry for the late answer. > Unfortunately, the patch in this form doesn't apply any more on > trunk. If you have the time, please consider adapting it so we can > try it. Sure. Please try the following patch. YAMAMOTO Mitsuharu mituharu@math.s.chiba-u.ac.jp === modified file 'lisp/frame.el' *** lisp/frame.el 2013-05-11 02:27:28 +0000 --- lisp/frame.el 2013-05-11 03:30:27 +0000 *************** *** 1365,1371 **** (defun display-pixel-height (&optional display) "Return the height of DISPLAY's screen in pixels. ! For character terminals, each character counts as a single pixel." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) --- 1365,1375 ---- (defun display-pixel-height (&optional display) "Return the height of DISPLAY's screen in pixels. ! For character terminals, each character counts as a single pixel. ! For graphical terminals, note that 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'." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) *************** *** 1377,1383 **** (defun display-pixel-width (&optional display) "Return the width of DISPLAY's screen in pixels. ! For character terminals, each character counts as a single pixel." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) --- 1381,1391 ---- (defun display-pixel-width (&optional display) "Return the width of DISPLAY's screen in pixels. ! For character terminals, each character counts as a single pixel. ! For graphical terminals, note that 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'." (let ((frame-type (framep-on-display display))) (cond ((memq frame-type '(x w32 ns)) *************** *** 1408,1414 **** (defun display-mm-height (&optional display) "Return the height of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. ! If the information is unavailable, value is nil." (and (memq (framep-on-display display) '(x w32 ns)) (or (cddr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) --- 1416,1426 ---- (defun display-mm-height (&optional display) "Return the height of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. ! If the information is unavailable, value is nil. ! For graphical terminals, note that 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'." (and (memq (framep-on-display display) '(x w32 ns)) (or (cddr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) *************** *** 1420,1426 **** (defun display-mm-width (&optional display) "Return the width of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. ! If the information is unavailable, value is nil." (and (memq (framep-on-display display) '(x w32 ns)) (or (cadr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) --- 1432,1442 ---- (defun display-mm-width (&optional display) "Return the width of DISPLAY's screen in millimeters. System values can be overridden by `display-mm-dimensions-alist'. ! If the information is unavailable, value is nil. ! For graphical terminals, note that on \"multi-monitor\" setups this ! refers to the width in millimeters for all physical monitors ! associated with DISPLAY. To get information for each physical ! monitor, use `display-monitor-attributes-list'." (and (memq (framep-on-display display) '(x w32 ns)) (or (cadr (assoc (or display (frame-parameter nil 'display)) display-mm-dimensions-alist)) *************** *** 1495,1500 **** --- 1511,1518 ---- (declare-function x-display-monitor-attributes-list "xfns.c" (&optional terminal)) + (declare-function w32-display-monitor-attributes-list "w32fns.c" + (&optional display)) (declare-function ns-display-monitor-attributes-list "nsfns.m" (&optional terminal)) *************** *** 1530,1535 **** --- 1548,1555 ---- (cond ((eq frame-type 'x) (x-display-monitor-attributes-list display)) + ((eq frame-type 'w32) + (w32-display-monitor-attributes-list display)) ((eq frame-type 'ns) (ns-display-monitor-attributes-list display)) (t === modified file 'src/w32fns.c' *** src/w32fns.c 2013-06-20 17:36:24 +0000 --- src/w32fns.c 2013-06-20 23:51:45 +0000 *************** *** 106,111 **** --- 106,112 ---- Lisp_Object Qctrl; Lisp_Object Qcontrol; Lisp_Object Qshift; + static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes; /* Prefix for system colors. */ *************** *** 131,136 **** --- 132,146 ---- #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 *************** *** 141,146 **** --- 151,168 ---- 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); *************** *** 159,164 **** --- 181,190 ---- (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; *************** *** 168,173 **** --- 194,200 ---- 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 *************** *** 4674,4680 **** 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. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); --- 4701,4711 ---- 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. ! ! 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); *************** *** 4687,4693 **** 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. */) (Lisp_Object display) { struct w32_display_info *dpyinfo = check_x_display_info (display); --- 4718,4728 ---- 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. ! ! 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); *************** *** 4779,4819 **** 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. */) (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); ! ! ReleaseDC (dpyinfo->root_window, hdc); ! ! return make_number (cap); } 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. */) (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); ! ReleaseDC (dpyinfo->root_window, hdc); ! ! return make_number (cap); } DEFUN ("x-display-backing-store", Fx_display_backing_store, --- 4814,4859 ---- 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. ! ! 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; ! double mm_per_pixel; ! hdc = GetDC (NULL); ! mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE) ! / GetDeviceCaps (hdc, VERTRES)); ! ReleaseDC (NULL, hdc); ! 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. ! ! 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; ! double mm_per_pixel; ! hdc = GetDC (NULL); ! mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE) ! / GetDeviceCaps (hdc, HORZRES)); ! ReleaseDC (NULL, hdc); ! return make_number (x_display_pixel_width (dpyinfo) * mm_per_pixel + 0.5); } DEFUN ("x-display-backing-store", Fx_display_backing_store, *************** *** 4865,4870 **** --- 4905,5106 ---- 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_pointer (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 (make_unibyte_string (mi.szDevice, + strlen (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 *************** *** 7357,7362 **** --- 7593,7602 ---- 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. */ *************** *** 7635,7640 **** --- 7875,7881 ---- defsubr (&Sx_display_visual_class); defsubr (&Sx_display_backing_store); defsubr (&Sx_display_save_under); + defsubr (&Sw32_display_monitor_attributes_list); defsubr (&Sx_create_frame); defsubr (&Sx_open_connection); defsubr (&Sx_close_connection); *************** *** 7707,7712 **** --- 7948,7955 ---- 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"); === modified file 'src/w32term.c' *** src/w32term.c 2013-06-20 17:36:24 +0000 --- src/w32term.c 2013-06-20 23:51:45 +0000 *************** *** 143,148 **** --- 143,157 ---- #define WS_EX_LAYERED 0x80000 #endif + /* SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN are not defined on 95 and + NT4. */ + #ifndef SM_CXVIRTUALSCREEN + #define SM_CXVIRTUALSCREEN 78 + #endif + #ifndef SM_CYVIRTUALSCREEN + #define SM_CXVIRTUALSCREEN 79 + #endif + /* This is a frame waiting to be autoraised, within w32_read_socket. */ struct frame *pending_autoraise_frame; *************** *** 519,536 **** int x_display_pixel_height (struct w32_display_info *dpyinfo) { ! HDC dc = GetDC (NULL); ! int pixels = GetDeviceCaps (dc, VERTRES); ! ReleaseDC (NULL, dc); return pixels; } int x_display_pixel_width (struct w32_display_info *dpyinfo) { ! HDC dc = GetDC (NULL); ! int pixels = GetDeviceCaps (dc, HORZRES); ! ReleaseDC (NULL, dc); return pixels; } --- 528,551 ---- int x_display_pixel_height (struct w32_display_info *dpyinfo) { ! int pixels = GetSystemMetrics (SM_CYVIRTUALSCREEN); ! ! if (pixels == 0) ! /* Fallback for Windows 95 or NT 4.0. */ ! pixels = GetSystemMetrics (SM_CYSCREEN); ! return pixels; } int x_display_pixel_width (struct w32_display_info *dpyinfo) { ! int pixels = GetSystemMetrics (SM_CXVIRTUALSCREEN); ! ! if (pixels == 0) ! /* Fallback for Windows 95 or NT 4.0. */ ! pixels = GetSystemMetrics (SM_CXSCREEN); ! return pixels; }