diff options
| author | YAMAMOTO Mitsuharu | 2013-07-04 19:25:54 +0900 |
|---|---|---|
| committer | YAMAMOTO Mitsuharu | 2013-07-04 19:25:54 +0900 |
| commit | cf13177e99d20e8db632ad6ed5defd3818f7d901 (patch) | |
| tree | 8cbc52eb53375dfbb2eb4eba3dff92453385e186 /src | |
| parent | 46e4f8217a5379bfab2a0f9c78e2a6a23a9d3cf1 (diff) | |
| download | emacs-cf13177e99d20e8db632ad6ed5defd3818f7d901.tar.gz emacs-cf13177e99d20e8db632ad6ed5defd3818f7d901.zip | |
Add multi-monitor support on W32.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 24 | ||||
| -rw-r--r-- | src/w32fns.c | 281 | ||||
| -rw-r--r-- | src/w32term.c | 27 |
3 files changed, 307 insertions, 25 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 416e60f30a4..9012f5ba16a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,27 @@ | |||
| 1 | 2013-07-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 2 | |||
| 3 | * w32fns.c (Qgeometry, Qworkarea, Qmm_size, Qframes): New variables. | ||
| 4 | (syms_of_w32fns): DEFSYM them. | ||
| 5 | (MONITORINFOF_PRIMARY, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN) | ||
| 6 | (CCHDEVICENAME): Define macros if not defined. | ||
| 7 | (struct MONITOR_INFO_EX): New struct. | ||
| 8 | (MonitorEnum_Proc, EnumDisplayMonitors_Proc): New prototypes. | ||
| 9 | (enum_display_monitors_fn): New variable. | ||
| 10 | (globals_of_w32fns): Initialize it. | ||
| 11 | (Fx_display_pixel_width, Fx_display_pixel_height) | ||
| 12 | (Fx_display_mm_height, Fx_display_mm_width): Mention behavior on | ||
| 13 | multi-monitor setups in docstrings. | ||
| 14 | (Fx_display_mm_height, Fx_display_mm_width): Approximate whole | ||
| 15 | screen size by primary monitor's millimeter per pixel. | ||
| 16 | (w32_monitor_enum, w32_display_monitor_attributes_list) | ||
| 17 | (w32_display_monitor_attributes_list_fallback) | ||
| 18 | (Fw32_display_monitor_attributes_list): New functions. | ||
| 19 | (syms_of_w32fns): Defsubr Sw32_display_monitor_attributes_list. | ||
| 20 | |||
| 21 | * w32term.c (SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN): Define macros | ||
| 22 | if not defined. | ||
| 23 | (x_display_pixel_height, x_display_pixel_width): Use GetSystemMetrics. | ||
| 24 | |||
| 1 | 2013-07-04 Michael Albinus <michael.albinus@gmx.de> | 25 | 2013-07-04 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 26 | ||
| 3 | * fileio.c (Qfile_notify_error): New error symbol. | 27 | * fileio.c (Qfile_notify_error): New error symbol. |
diff --git a/src/w32fns.c b/src/w32fns.c index 46fb02d96a1..3fa23c166e2 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -106,6 +106,7 @@ Lisp_Object Qalt; | |||
| 106 | Lisp_Object Qctrl; | 106 | Lisp_Object Qctrl; |
| 107 | Lisp_Object Qcontrol; | 107 | Lisp_Object Qcontrol; |
| 108 | Lisp_Object Qshift; | 108 | Lisp_Object Qshift; |
| 109 | static Lisp_Object Qgeometry, Qworkarea, Qmm_size, Qframes; | ||
| 109 | 110 | ||
| 110 | 111 | ||
| 111 | /* Prefix for system colors. */ | 112 | /* Prefix for system colors. */ |
| @@ -131,6 +132,15 @@ static HWND track_mouse_window; | |||
| 131 | #ifndef MONITOR_DEFAULT_TO_NEAREST | 132 | #ifndef MONITOR_DEFAULT_TO_NEAREST |
| 132 | #define MONITOR_DEFAULT_TO_NEAREST 2 | 133 | #define MONITOR_DEFAULT_TO_NEAREST 2 |
| 133 | #endif | 134 | #endif |
| 135 | #ifndef MONITORINFOF_PRIMARY | ||
| 136 | #define MONITORINFOF_PRIMARY 1 | ||
| 137 | #endif | ||
| 138 | #ifndef SM_XVIRTUALSCREEN | ||
| 139 | #define SM_XVIRTUALSCREEN 76 | ||
| 140 | #endif | ||
| 141 | #ifndef SM_YVIRTUALSCREEN | ||
| 142 | #define SM_YVIRTUALSCREEN 77 | ||
| 143 | #endif | ||
| 134 | /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't. | 144 | /* MinGW headers define MONITORINFO unconditionally, but MSVC ones don't. |
| 135 | To avoid a compile error on one or the other, redefine with a new name. */ | 145 | To avoid a compile error on one or the other, redefine with a new name. */ |
| 136 | struct MONITOR_INFO | 146 | struct MONITOR_INFO |
| @@ -141,6 +151,18 @@ struct MONITOR_INFO | |||
| 141 | DWORD dwFlags; | 151 | DWORD dwFlags; |
| 142 | }; | 152 | }; |
| 143 | 153 | ||
| 154 | #ifndef CCHDEVICENAME | ||
| 155 | #define CCHDEVICENAME 32 | ||
| 156 | #endif | ||
| 157 | struct MONITOR_INFO_EX | ||
| 158 | { | ||
| 159 | DWORD cbSize; | ||
| 160 | RECT rcMonitor; | ||
| 161 | RECT rcWork; | ||
| 162 | DWORD dwFlags; | ||
| 163 | char szDevice[CCHDEVICENAME]; | ||
| 164 | }; | ||
| 165 | |||
| 144 | /* Reportedly, MSVC does not have this in its headers. */ | 166 | /* Reportedly, MSVC does not have this in its headers. */ |
| 145 | #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500 | 167 | #if defined (_MSC_VER) && _WIN32_WINNT < 0x0500 |
| 146 | DECLARE_HANDLE(HMONITOR); | 168 | DECLARE_HANDLE(HMONITOR); |
| @@ -159,6 +181,10 @@ typedef BOOL (WINAPI * GetMonitorInfo_Proc) | |||
| 159 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); | 181 | (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); |
| 160 | typedef HMONITOR (WINAPI * MonitorFromWindow_Proc) | 182 | typedef HMONITOR (WINAPI * MonitorFromWindow_Proc) |
| 161 | (IN HWND hwnd, IN DWORD dwFlags); | 183 | (IN HWND hwnd, IN DWORD dwFlags); |
| 184 | typedef BOOL CALLBACK (* MonitorEnum_Proc) | ||
| 185 | (IN HMONITOR monitor, IN HDC hdc, IN RECT *rcMonitor, IN LPARAM dwData); | ||
| 186 | typedef BOOL (WINAPI * EnumDisplayMonitors_Proc) | ||
| 187 | (IN HDC hdc, IN RECT *rcClip, IN MonitorEnum_Proc fnEnum, IN LPARAM dwData); | ||
| 162 | 188 | ||
| 163 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; | 189 | TrackMouseEvent_Proc track_mouse_event_fn = NULL; |
| 164 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; | 190 | ImmGetCompositionString_Proc get_composition_string_fn = NULL; |
| @@ -168,6 +194,7 @@ ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; | |||
| 168 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; | 194 | MonitorFromPoint_Proc monitor_from_point_fn = NULL; |
| 169 | GetMonitorInfo_Proc get_monitor_info_fn = NULL; | 195 | GetMonitorInfo_Proc get_monitor_info_fn = NULL; |
| 170 | MonitorFromWindow_Proc monitor_from_window_fn = NULL; | 196 | MonitorFromWindow_Proc monitor_from_window_fn = NULL; |
| 197 | EnumDisplayMonitors_Proc enum_display_monitors_fn = NULL; | ||
| 171 | 198 | ||
| 172 | #ifdef NTGUI_UNICODE | 199 | #ifdef NTGUI_UNICODE |
| 173 | #define unicode_append_menu AppendMenuW | 200 | #define unicode_append_menu AppendMenuW |
| @@ -4674,7 +4701,11 @@ DEFUN ("x-display-pixel-width", Fx_display_pixel_width, | |||
| 4674 | doc: /* Return the width in pixels of DISPLAY. | 4701 | doc: /* Return the width in pixels of DISPLAY. |
| 4675 | The optional argument DISPLAY specifies which display to ask about. | 4702 | The optional argument DISPLAY specifies which display to ask about. |
| 4676 | DISPLAY should be either a frame or a display name (a string). | 4703 | DISPLAY should be either a frame or a display name (a string). |
| 4677 | If omitted or nil, that stands for the selected frame's display. */) | 4704 | If omitted or nil, that stands for the selected frame's display. |
| 4705 | |||
| 4706 | On \"multi-monitor\" setups this refers to the pixel width for all | ||
| 4707 | physical monitors associated with DISPLAY. To get information for | ||
| 4708 | each physical monitor, use `display-monitor-attributes-list'. */) | ||
| 4678 | (Lisp_Object display) | 4709 | (Lisp_Object display) |
| 4679 | { | 4710 | { |
| 4680 | struct w32_display_info *dpyinfo = check_x_display_info (display); | 4711 | struct w32_display_info *dpyinfo = check_x_display_info (display); |
| @@ -4687,7 +4718,11 @@ DEFUN ("x-display-pixel-height", Fx_display_pixel_height, | |||
| 4687 | doc: /* Return the height in pixels of DISPLAY. | 4718 | doc: /* Return the height in pixels of DISPLAY. |
| 4688 | The optional argument DISPLAY specifies which display to ask about. | 4719 | The optional argument DISPLAY specifies which display to ask about. |
| 4689 | DISPLAY should be either a frame or a display name (a string). | 4720 | DISPLAY should be either a frame or a display name (a string). |
| 4690 | If omitted or nil, that stands for the selected frame's display. */) | 4721 | If omitted or nil, that stands for the selected frame's display. |
| 4722 | |||
| 4723 | On \"multi-monitor\" setups this refers to the pixel height for all | ||
| 4724 | physical monitors associated with DISPLAY. To get information for | ||
| 4725 | each physical monitor, use `display-monitor-attributes-list'. */) | ||
| 4691 | (Lisp_Object display) | 4726 | (Lisp_Object display) |
| 4692 | { | 4727 | { |
| 4693 | struct w32_display_info *dpyinfo = check_x_display_info (display); | 4728 | struct w32_display_info *dpyinfo = check_x_display_info (display); |
| @@ -4779,41 +4814,46 @@ DEFUN ("x-display-mm-height", Fx_display_mm_height, | |||
| 4779 | doc: /* Return the height in millimeters of DISPLAY. | 4814 | doc: /* Return the height in millimeters of DISPLAY. |
| 4780 | The optional argument DISPLAY specifies which display to ask about. | 4815 | The optional argument DISPLAY specifies which display to ask about. |
| 4781 | DISPLAY should be either a frame or a display name (a string). | 4816 | DISPLAY should be either a frame or a display name (a string). |
| 4782 | If omitted or nil, that stands for the selected frame's display. */) | 4817 | If omitted or nil, that stands for the selected frame's display. |
| 4818 | |||
| 4819 | On \"multi-monitor\" setups this refers to the height in millimeters for | ||
| 4820 | all physical monitors associated with DISPLAY. To get information | ||
| 4821 | for each physical monitor, use `display-monitor-attributes-list'. */) | ||
| 4783 | (Lisp_Object display) | 4822 | (Lisp_Object display) |
| 4784 | { | 4823 | { |
| 4785 | struct w32_display_info *dpyinfo = check_x_display_info (display); | 4824 | struct w32_display_info *dpyinfo = check_x_display_info (display); |
| 4786 | HDC hdc; | 4825 | HDC hdc; |
| 4787 | int cap; | 4826 | double mm_per_pixel; |
| 4788 | |||
| 4789 | hdc = GetDC (dpyinfo->root_window); | ||
| 4790 | 4827 | ||
| 4791 | cap = GetDeviceCaps (hdc, VERTSIZE); | 4828 | hdc = GetDC (NULL); |
| 4829 | mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE) | ||
| 4830 | / GetDeviceCaps (hdc, VERTRES)); | ||
| 4831 | ReleaseDC (NULL, hdc); | ||
| 4792 | 4832 | ||
| 4793 | ReleaseDC (dpyinfo->root_window, hdc); | 4833 | return make_number (x_display_pixel_height (dpyinfo) * mm_per_pixel + 0.5); |
| 4794 | |||
| 4795 | return make_number (cap); | ||
| 4796 | } | 4834 | } |
| 4797 | 4835 | ||
| 4798 | DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, | 4836 | DEFUN ("x-display-mm-width", Fx_display_mm_width, Sx_display_mm_width, 0, 1, 0, |
| 4799 | doc: /* Return the width in millimeters of DISPLAY. | 4837 | doc: /* Return the width in millimeters of DISPLAY. |
| 4800 | The optional argument DISPLAY specifies which display to ask about. | 4838 | The optional argument DISPLAY specifies which display to ask about. |
| 4801 | DISPLAY should be either a frame or a display name (a string). | 4839 | DISPLAY should be either a frame or a display name (a string). |
| 4802 | If omitted or nil, that stands for the selected frame's display. */) | 4840 | If omitted or nil, that stands for the selected frame's display. |
| 4841 | |||
| 4842 | On \"multi-monitor\" setups this refers to the width in millimeters for | ||
| 4843 | all physical monitors associated with TERMINAL. To get information | ||
| 4844 | for each physical monitor, use `display-monitor-attributes-list'. */) | ||
| 4803 | (Lisp_Object display) | 4845 | (Lisp_Object display) |
| 4804 | { | 4846 | { |
| 4805 | struct w32_display_info *dpyinfo = check_x_display_info (display); | 4847 | struct w32_display_info *dpyinfo = check_x_display_info (display); |
| 4806 | |||
| 4807 | HDC hdc; | 4848 | HDC hdc; |
| 4808 | int cap; | 4849 | double mm_per_pixel; |
| 4809 | 4850 | ||
| 4810 | hdc = GetDC (dpyinfo->root_window); | 4851 | hdc = GetDC (NULL); |
| 4852 | mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE) | ||
| 4853 | / GetDeviceCaps (hdc, HORZRES)); | ||
| 4854 | ReleaseDC (NULL, hdc); | ||
| 4811 | 4855 | ||
| 4812 | cap = GetDeviceCaps (hdc, HORZSIZE); | 4856 | return make_number (x_display_pixel_width (dpyinfo) * mm_per_pixel + 0.5); |
| 4813 | |||
| 4814 | ReleaseDC (dpyinfo->root_window, hdc); | ||
| 4815 | |||
| 4816 | return make_number (cap); | ||
| 4817 | } | 4857 | } |
| 4818 | 4858 | ||
| 4819 | DEFUN ("x-display-backing-store", Fx_display_backing_store, | 4859 | DEFUN ("x-display-backing-store", Fx_display_backing_store, |
| @@ -4865,6 +4905,202 @@ If omitted or nil, that stands for the selected frame's display. */) | |||
| 4865 | return Qnil; | 4905 | return Qnil; |
| 4866 | } | 4906 | } |
| 4867 | 4907 | ||
| 4908 | static BOOL CALLBACK | ||
| 4909 | w32_monitor_enum (HMONITOR monitor, HDC hdc, RECT *rcMonitor, LPARAM dwData) | ||
| 4910 | { | ||
| 4911 | Lisp_Object *monitor_list = (Lisp_Object *) dwData; | ||
| 4912 | |||
| 4913 | *monitor_list = Fcons (make_save_pointer (monitor), *monitor_list); | ||
| 4914 | |||
| 4915 | return TRUE; | ||
| 4916 | } | ||
| 4917 | |||
| 4918 | static Lisp_Object | ||
| 4919 | w32_display_monitor_attributes_list (void) | ||
| 4920 | { | ||
| 4921 | Lisp_Object attributes_list = Qnil, primary_monitor_attributes = Qnil; | ||
| 4922 | Lisp_Object monitor_list = Qnil, monitor_frames, rest, frame; | ||
| 4923 | int i, n_monitors; | ||
| 4924 | HMONITOR *monitors; | ||
| 4925 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 4926 | |||
| 4927 | if (!(enum_display_monitors_fn && get_monitor_info_fn | ||
| 4928 | && monitor_from_window_fn)) | ||
| 4929 | return Qnil; | ||
| 4930 | |||
| 4931 | if (!enum_display_monitors_fn (NULL, NULL, w32_monitor_enum, | ||
| 4932 | (LPARAM) &monitor_list) | ||
| 4933 | || NILP (monitor_list)) | ||
| 4934 | return Qnil; | ||
| 4935 | |||
| 4936 | n_monitors = 0; | ||
| 4937 | for (rest = monitor_list; CONSP (rest); rest = XCDR (rest)) | ||
| 4938 | n_monitors++; | ||
| 4939 | |||
| 4940 | monitors = xmalloc (n_monitors * sizeof (*monitors)); | ||
| 4941 | for (i = 0; i < n_monitors; i++) | ||
| 4942 | { | ||
| 4943 | monitors[i] = XSAVE_POINTER (XCAR (monitor_list), 0); | ||
| 4944 | monitor_list = XCDR (monitor_list); | ||
| 4945 | } | ||
| 4946 | |||
| 4947 | monitor_frames = Fmake_vector (make_number (n_monitors), Qnil); | ||
| 4948 | FOR_EACH_FRAME (rest, frame) | ||
| 4949 | { | ||
| 4950 | struct frame *f = XFRAME (frame); | ||
| 4951 | |||
| 4952 | if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) | ||
| 4953 | { | ||
| 4954 | HMONITOR monitor = | ||
| 4955 | monitor_from_window_fn (FRAME_W32_WINDOW (f), | ||
| 4956 | MONITOR_DEFAULT_TO_NEAREST); | ||
| 4957 | |||
| 4958 | for (i = 0; i < n_monitors; i++) | ||
| 4959 | if (monitors[i] == monitor) | ||
| 4960 | break; | ||
| 4961 | |||
| 4962 | if (i < n_monitors) | ||
| 4963 | ASET (monitor_frames, i, Fcons (frame, AREF (monitor_frames, i))); | ||
| 4964 | } | ||
| 4965 | } | ||
| 4966 | |||
| 4967 | GCPRO3 (attributes_list, primary_monitor_attributes, monitor_frames); | ||
| 4968 | |||
| 4969 | for (i = 0; i < n_monitors; i++) | ||
| 4970 | { | ||
| 4971 | Lisp_Object geometry, workarea, name, attributes = Qnil; | ||
| 4972 | HDC hdc; | ||
| 4973 | int width_mm, height_mm; | ||
| 4974 | struct MONITOR_INFO_EX mi; | ||
| 4975 | |||
| 4976 | mi.cbSize = sizeof (mi); | ||
| 4977 | if (!get_monitor_info_fn (monitors[i], (struct MONITOR_INFO *) &mi)) | ||
| 4978 | continue; | ||
| 4979 | |||
| 4980 | hdc = CreateDCA ("DISPLAY", mi.szDevice, NULL, NULL); | ||
| 4981 | if (hdc == NULL) | ||
| 4982 | continue; | ||
| 4983 | width_mm = GetDeviceCaps (hdc, HORZSIZE); | ||
| 4984 | height_mm = GetDeviceCaps (hdc, VERTSIZE); | ||
| 4985 | DeleteDC (hdc); | ||
| 4986 | |||
| 4987 | attributes = Fcons (Fcons (Qframes, AREF (monitor_frames, i)), | ||
| 4988 | attributes); | ||
| 4989 | |||
| 4990 | name = DECODE_SYSTEM (make_unibyte_string (mi.szDevice, | ||
| 4991 | strlen (mi.szDevice))); | ||
| 4992 | attributes = Fcons (Fcons (Qname, name), attributes); | ||
| 4993 | |||
| 4994 | attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), | ||
| 4995 | attributes); | ||
| 4996 | |||
| 4997 | workarea = list4i (mi.rcWork.left, mi.rcWork.top, | ||
| 4998 | mi.rcWork.right - mi.rcWork.left, | ||
| 4999 | mi.rcWork.bottom - mi.rcWork.top); | ||
| 5000 | attributes = Fcons (Fcons (Qworkarea, workarea), attributes); | ||
| 5001 | |||
| 5002 | geometry = list4i (mi.rcMonitor.left, mi.rcMonitor.top, | ||
| 5003 | mi.rcMonitor.right - mi.rcMonitor.left, | ||
| 5004 | mi.rcMonitor.bottom - mi.rcMonitor.top); | ||
| 5005 | attributes = Fcons (Fcons (Qgeometry, geometry), attributes); | ||
| 5006 | |||
| 5007 | if (mi.dwFlags & MONITORINFOF_PRIMARY) | ||
| 5008 | primary_monitor_attributes = attributes; | ||
| 5009 | else | ||
| 5010 | attributes_list = Fcons (attributes, attributes_list); | ||
| 5011 | } | ||
| 5012 | |||
| 5013 | if (!NILP (primary_monitor_attributes)) | ||
| 5014 | attributes_list = Fcons (primary_monitor_attributes, attributes_list); | ||
| 5015 | |||
| 5016 | UNGCPRO; | ||
| 5017 | |||
| 5018 | xfree (monitors); | ||
| 5019 | |||
| 5020 | return attributes_list; | ||
| 5021 | } | ||
| 5022 | |||
| 5023 | static Lisp_Object | ||
| 5024 | w32_display_monitor_attributes_list_fallback (struct w32_display_info *dpyinfo) | ||
| 5025 | { | ||
| 5026 | Lisp_Object geometry, workarea, frames, rest, frame, attributes = Qnil; | ||
| 5027 | HDC hdc; | ||
| 5028 | double mm_per_pixel; | ||
| 5029 | int pixel_width, pixel_height, width_mm, height_mm; | ||
| 5030 | RECT workarea_rect; | ||
| 5031 | |||
| 5032 | /* Fallback: treat (possibly) multiple physical monitors as if they | ||
| 5033 | formed a single monitor as a whole. This should provide a | ||
| 5034 | consistent result at least on single monitor environments. */ | ||
| 5035 | attributes = Fcons (Fcons (Qname, build_string ("combined screen")), | ||
| 5036 | attributes); | ||
| 5037 | |||
| 5038 | frames = Qnil; | ||
| 5039 | FOR_EACH_FRAME (rest, frame) | ||
| 5040 | { | ||
| 5041 | struct frame *f = XFRAME (frame); | ||
| 5042 | |||
| 5043 | if (FRAME_W32_P (f) && !EQ (frame, tip_frame)) | ||
| 5044 | frames = Fcons (frame, frames); | ||
| 5045 | } | ||
| 5046 | attributes = Fcons (Fcons (Qframes, frames), attributes); | ||
| 5047 | |||
| 5048 | pixel_width = x_display_pixel_width (dpyinfo); | ||
| 5049 | pixel_height = x_display_pixel_height (dpyinfo); | ||
| 5050 | |||
| 5051 | hdc = GetDC (NULL); | ||
| 5052 | mm_per_pixel = ((double) GetDeviceCaps (hdc, HORZSIZE) | ||
| 5053 | / GetDeviceCaps (hdc, HORZRES)); | ||
| 5054 | width_mm = pixel_width * mm_per_pixel + 0.5; | ||
| 5055 | mm_per_pixel = ((double) GetDeviceCaps (hdc, VERTSIZE) | ||
| 5056 | / GetDeviceCaps (hdc, VERTRES)); | ||
| 5057 | height_mm = pixel_height * mm_per_pixel + 0.5; | ||
| 5058 | ReleaseDC (NULL, hdc); | ||
| 5059 | attributes = Fcons (Fcons (Qmm_size, list2i (width_mm, height_mm)), | ||
| 5060 | attributes); | ||
| 5061 | |||
| 5062 | /* GetSystemMetrics below may return 0 for Windows 95 or NT 4.0, but | ||
| 5063 | we don't care. */ | ||
| 5064 | geometry = list4i (GetSystemMetrics (SM_XVIRTUALSCREEN), | ||
| 5065 | GetSystemMetrics (SM_YVIRTUALSCREEN), | ||
| 5066 | pixel_width, pixel_height); | ||
| 5067 | if (SystemParametersInfo (SPI_GETWORKAREA, 0, &workarea_rect, 0)) | ||
| 5068 | workarea = list4i (workarea_rect.left, workarea_rect.top, | ||
| 5069 | workarea_rect.right - workarea_rect.left, | ||
| 5070 | workarea_rect.bottom - workarea_rect.top); | ||
| 5071 | else | ||
| 5072 | workarea = geometry; | ||
| 5073 | attributes = Fcons (Fcons (Qworkarea, workarea), attributes); | ||
| 5074 | |||
| 5075 | attributes = Fcons (Fcons (Qgeometry, geometry), attributes); | ||
| 5076 | |||
| 5077 | return list1 (attributes); | ||
| 5078 | } | ||
| 5079 | |||
| 5080 | DEFUN ("w32-display-monitor-attributes-list", Fw32_display_monitor_attributes_list, | ||
| 5081 | Sw32_display_monitor_attributes_list, | ||
| 5082 | 0, 1, 0, | ||
| 5083 | doc: /* Return a list of physical monitor attributes on the W32 display DISPLAY. | ||
| 5084 | |||
| 5085 | The optional argument DISPLAY specifies which display to ask about. | ||
| 5086 | DISPLAY should be either a frame or a display name (a string). | ||
| 5087 | If omitted or nil, that stands for the selected frame's display. | ||
| 5088 | |||
| 5089 | Internal use only, use `display-monitor-attributes-list' instead. */) | ||
| 5090 | (Lisp_Object display) | ||
| 5091 | { | ||
| 5092 | struct w32_display_info *dpyinfo = check_x_display_info (display); | ||
| 5093 | Lisp_Object attributes_list; | ||
| 5094 | |||
| 5095 | block_input (); | ||
| 5096 | attributes_list = w32_display_monitor_attributes_list (); | ||
| 5097 | if (NILP (attributes_list)) | ||
| 5098 | attributes_list = w32_display_monitor_attributes_list_fallback (dpyinfo); | ||
| 5099 | unblock_input (); | ||
| 5100 | |||
| 5101 | return attributes_list; | ||
| 5102 | } | ||
| 5103 | |||
| 4868 | DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0, | 5104 | DEFUN ("set-message-beep", Fset_message_beep, Sset_message_beep, 1, 1, 0, |
| 4869 | doc: /* Set the sound generated when the bell is rung. | 5105 | doc: /* Set the sound generated when the bell is rung. |
| 4870 | SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent | 5106 | SOUND is 'asterisk, 'exclamation, 'hand, 'question, 'ok, or 'silent |
| @@ -7357,6 +7593,10 @@ syms_of_w32fns (void) | |||
| 7357 | DEFSYM (Qcontrol, "control"); | 7593 | DEFSYM (Qcontrol, "control"); |
| 7358 | DEFSYM (Qshift, "shift"); | 7594 | DEFSYM (Qshift, "shift"); |
| 7359 | DEFSYM (Qfont_param, "font-parameter"); | 7595 | DEFSYM (Qfont_param, "font-parameter"); |
| 7596 | DEFSYM (Qgeometry, "geometry"); | ||
| 7597 | DEFSYM (Qworkarea, "workarea"); | ||
| 7598 | DEFSYM (Qmm_size, "mm-size"); | ||
| 7599 | DEFSYM (Qframes, "frames"); | ||
| 7360 | /* This is the end of symbol initialization. */ | 7600 | /* This is the end of symbol initialization. */ |
| 7361 | 7601 | ||
| 7362 | 7602 | ||
| @@ -7646,6 +7886,7 @@ only be necessary if the default setting causes problems. */); | |||
| 7646 | 7886 | ||
| 7647 | defsubr (&Sw32_define_rgb_color); | 7887 | defsubr (&Sw32_define_rgb_color); |
| 7648 | defsubr (&Sw32_default_color_map); | 7888 | defsubr (&Sw32_default_color_map); |
| 7889 | defsubr (&Sw32_display_monitor_attributes_list); | ||
| 7649 | defsubr (&Sw32_send_sys_command); | 7890 | defsubr (&Sw32_send_sys_command); |
| 7650 | defsubr (&Sw32_shell_execute); | 7891 | defsubr (&Sw32_shell_execute); |
| 7651 | defsubr (&Sw32_register_hot_key); | 7892 | defsubr (&Sw32_register_hot_key); |
| @@ -7707,6 +7948,8 @@ globals_of_w32fns (void) | |||
| 7707 | GetProcAddress (user32_lib, "GetMonitorInfoA"); | 7948 | GetProcAddress (user32_lib, "GetMonitorInfoA"); |
| 7708 | monitor_from_window_fn = (MonitorFromWindow_Proc) | 7949 | monitor_from_window_fn = (MonitorFromWindow_Proc) |
| 7709 | GetProcAddress (user32_lib, "MonitorFromWindow"); | 7950 | GetProcAddress (user32_lib, "MonitorFromWindow"); |
| 7951 | enum_display_monitors_fn = (EnumDisplayMonitors_Proc) | ||
| 7952 | GetProcAddress (user32_lib, "EnumDisplayMonitors"); | ||
| 7710 | 7953 | ||
| 7711 | { | 7954 | { |
| 7712 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); | 7955 | HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); |
diff --git a/src/w32term.c b/src/w32term.c index d3174c65bf0..fcd5886d5c9 100644 --- a/src/w32term.c +++ b/src/w32term.c | |||
| @@ -143,6 +143,15 @@ BOOL (WINAPI *pfnSetLayeredWindowAttributes) (HWND, COLORREF, BYTE, DWORD); | |||
| 143 | #define WS_EX_LAYERED 0x80000 | 143 | #define WS_EX_LAYERED 0x80000 |
| 144 | #endif | 144 | #endif |
| 145 | 145 | ||
| 146 | /* SM_CXVIRTUALSCREEN and SM_CYVIRTUALSCREEN are not defined on 95 and | ||
| 147 | NT4. */ | ||
| 148 | #ifndef SM_CXVIRTUALSCREEN | ||
| 149 | #define SM_CXVIRTUALSCREEN 78 | ||
| 150 | #endif | ||
| 151 | #ifndef SM_CYVIRTUALSCREEN | ||
| 152 | #define SM_CYVIRTUALSCREEN 79 | ||
| 153 | #endif | ||
| 154 | |||
| 146 | /* This is a frame waiting to be autoraised, within w32_read_socket. */ | 155 | /* This is a frame waiting to be autoraised, within w32_read_socket. */ |
| 147 | struct frame *pending_autoraise_frame; | 156 | struct frame *pending_autoraise_frame; |
| 148 | 157 | ||
| @@ -519,18 +528,24 @@ x_set_frame_alpha (struct frame *f) | |||
| 519 | int | 528 | int |
| 520 | x_display_pixel_height (struct w32_display_info *dpyinfo) | 529 | x_display_pixel_height (struct w32_display_info *dpyinfo) |
| 521 | { | 530 | { |
| 522 | HDC dc = GetDC (NULL); | 531 | int pixels = GetSystemMetrics (SM_CYVIRTUALSCREEN); |
| 523 | int pixels = GetDeviceCaps (dc, VERTRES); | 532 | |
| 524 | ReleaseDC (NULL, dc); | 533 | if (pixels == 0) |
| 534 | /* Fallback for Windows 95 or NT 4.0. */ | ||
| 535 | pixels = GetSystemMetrics (SM_CYSCREEN); | ||
| 536 | |||
| 525 | return pixels; | 537 | return pixels; |
| 526 | } | 538 | } |
| 527 | 539 | ||
| 528 | int | 540 | int |
| 529 | x_display_pixel_width (struct w32_display_info *dpyinfo) | 541 | x_display_pixel_width (struct w32_display_info *dpyinfo) |
| 530 | { | 542 | { |
| 531 | HDC dc = GetDC (NULL); | 543 | int pixels = GetSystemMetrics (SM_CXVIRTUALSCREEN); |
| 532 | int pixels = GetDeviceCaps (dc, HORZRES); | 544 | |
| 533 | ReleaseDC (NULL, dc); | 545 | if (pixels == 0) |
| 546 | /* Fallback for Windows 95 or NT 4.0. */ | ||
| 547 | pixels = GetSystemMetrics (SM_CXSCREEN); | ||
| 548 | |||
| 534 | return pixels; | 549 | return pixels; |
| 535 | } | 550 | } |
| 536 | 551 | ||