summaryrefslogtreecommitdiff
path: root/src/lib/ecore_win32
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2017-05-05 07:52:12 +0200
committerCedric BAIL <cedric@osg.samsung.com>2017-05-08 15:09:00 -0700
commit449b2a4bf3b072d039bcebfb7f811b75cb9644bc (patch)
treec55c3c21ee79c9d9298a3defb6b68f8c151db90d /src/lib/ecore_win32
parent122c34b2ceb460db93a74aef765747e9498e9bfa (diff)
Ecore_Win32: add API to retrieve the geometry and dpi of plugged displays
@feature Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/lib/ecore_win32')
-rw-r--r--src/lib/ecore_win32/Ecore_Win32.h29
-rw-r--r--src/lib/ecore_win32/ecore_win32.c20
-rw-r--r--src/lib/ecore_win32/ecore_win32_monitor.c224
-rw-r--r--src/lib/ecore_win32/ecore_win32_private.h11
4 files changed, 281 insertions, 3 deletions
diff --git a/src/lib/ecore_win32/Ecore_Win32.h b/src/lib/ecore_win32/Ecore_Win32.h
index 19a8b2ccb1..34e8596fdb 100644
--- a/src/lib/ecore_win32/Ecore_Win32.h
+++ b/src/lib/ecore_win32/Ecore_Win32.h
@@ -741,6 +741,35 @@ EAPI Eina_Bool ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
741EAPI Eina_Bool ecore_win32_clipboard_clear(const Ecore_Win32_Window *window); 741EAPI Eina_Bool ecore_win32_clipboard_clear(const Ecore_Win32_Window *window);
742 742
743/** 743/**
744 * @typedef Ecore_Win32_Monitor
745 * Desktop geometry and dpi of a monitor.
746 *
747 * @since 1.20
748 */
749typedef struct
750{
751 Eina_Rectangle desktop; /**< Coordinates and size of the desktop */
752 struct
753 {
754 unsigned int x; /**< DPI along the X axis */
755 unsigned int y; /**< DPI along the Y axis */
756 } dpi;
757} Ecore_Win32_Monitor;
758
759/**
760 * @brief Return the coordinates, sizes DPI's of the monitors.
761 *
762 * @return An iterator of an Eina list, with #Ecore_Win32_Monitor
763 * as data.
764 *
765 * This function returns the coordinates, sizes and DPI's of the
766 * monitors as an iterator of a list of #Ecore_Win32_Monitor.
767 *
768 * @since 1.20
769 */
770EAPI Eina_Iterator *ecore_win32_monitors_get(void);
771
772/**
744 * @} 773 * @}
745 */ 774 */
746 775
diff --git a/src/lib/ecore_win32/ecore_win32.c b/src/lib/ecore_win32/ecore_win32.c
index cd75bee28f..7b170c954d 100644
--- a/src/lib/ecore_win32/ecore_win32.c
+++ b/src/lib/ecore_win32/ecore_win32.c
@@ -8,6 +8,7 @@
8#include <windows.h> 8#include <windows.h>
9#undef WIN32_LEAN_AND_MEAN 9#undef WIN32_LEAN_AND_MEAN
10#include <windowsx.h> 10#include <windowsx.h>
11#include <dbt.h>
11 12
12#include <Eina.h> 13#include <Eina.h>
13#include <Ecore.h> 14#include <Ecore.h>
@@ -209,6 +210,7 @@ _ecore_win32_window_procedure(HWND window,
209 efl_AddClipboardFormatListener acfl; 210 efl_AddClipboardFormatListener acfl;
210 211
211 INF("create window message"); 212 INF("create window message");
213
212 acfl = (efl_AddClipboardFormatListener)GetProcAddress(GetModuleHandle("user32.dll"), 214 acfl = (efl_AddClipboardFormatListener)GetProcAddress(GetModuleHandle("user32.dll"),
213 "AddClipboardFormatListener"); 215 "AddClipboardFormatListener");
214 if (acfl) 216 if (acfl)
@@ -386,6 +388,20 @@ _ecore_win32_window_procedure(HWND window,
386 case WM_SYNCPAINT: 388 case WM_SYNCPAINT:
387 INF("sync paint message"); 389 INF("sync paint message");
388 return 0; 390 return 0;
391 /* Desktop notifications */
392 case WM_DEVICECHANGE:
393 if (window == ecore_win32_monitor_window)
394 {
395 PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)data_param;
396
397 if ((window_param == DBT_DEVICEARRIVAL) &&
398 (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
399 ecore_win32_monitor_update(1);
400
401 if ((window_param == DBT_DEVICEREMOVECOMPLETE) &&
402 (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
403 ecore_win32_monitor_update(2);
404 }
389 default: 405 default:
390 return DefWindowProc(window, message, window_param, data_param); 406 return DefWindowProc(window, message, window_param, data_param);
391 } 407 }
@@ -578,6 +594,8 @@ ecore_win32_init()
578 for (i = 0; i < 77; i++) 594 for (i = 0; i < 77; i++)
579 _ecore_win32_cursor_x[i] = _ecore_win32_cursor_x11_shaped_new(i); 595 _ecore_win32_cursor_x[i] = _ecore_win32_cursor_x11_shaped_new(i);
580 596
597 ecore_win32_monitor_init();
598
581 return _ecore_win32_init_count; 599 return _ecore_win32_init_count;
582 600
583 unregister_class: 601 unregister_class:
@@ -612,6 +630,8 @@ ecore_win32_shutdown()
612 if (--_ecore_win32_init_count != 0) 630 if (--_ecore_win32_init_count != 0)
613 return _ecore_win32_init_count; 631 return _ecore_win32_init_count;
614 632
633 ecore_win32_monitor_shutdown();
634
615 for (i = 0; i < 77; i++) 635 for (i = 0; i < 77; i++)
616 ecore_win32_cursor_free(_ecore_win32_cursor_x[i]); 636 ecore_win32_cursor_free(_ecore_win32_cursor_x[i]);
617 637
diff --git a/src/lib/ecore_win32/ecore_win32_monitor.c b/src/lib/ecore_win32/ecore_win32_monitor.c
new file mode 100644
index 0000000000..36d136908e
--- /dev/null
+++ b/src/lib/ecore_win32/ecore_win32_monitor.c
@@ -0,0 +1,224 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <stdlib.h>
6
7#define WIN32_LEAN_AND_MEAN
8#include <windows.h>
9#undef WIN32_LEAN_AND_MEAN
10#include <dbt.h>
11
12#include <Eina.h>
13
14#include "Ecore_Win32.h"
15#include "ecore_win32_private.h"
16
17/*============================================================================*
18 * Local *
19 *============================================================================*/
20
21/**
22 * @cond LOCAL
23 */
24
25typedef struct
26{
27 Ecore_Win32_Monitor monitor;
28 char *name;
29 Eina_Bool delete_me : 1;
30} Ecore_Win32_Monitor_Priv;
31
32typedef HRESULT (WINAPI *GetDpiForMonitor_t)(HMONITOR, int, UINT *, UINT *);
33
34static HMODULE _ecore_win32_mod = NULL;
35static GetDpiForMonitor_t GetDpiForMonitor_ = NULL;
36static Eina_List *ecore_win32_monitors = NULL;
37
38#ifndef GUID_DEVINTERFACE_MONITOR
39static GUID GUID_DEVINTERFACE_MONITOR = {0xe6f07b5f, 0xee97, 0x4a90, { 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7} };
40#endif
41
42static void
43_ecore_win32_monitor_free(void *p)
44{
45 Ecore_Win32_Monitor_Priv *ewm = p;
46
47 if (ewm)
48 {
49 free(ewm->name);
50 free(ewm);
51 }
52}
53
54static BOOL CALLBACK
55_ecore_win32_monitor_update_cb(HMONITOR m, HDC monitor EINA_UNUSED, LPRECT r EINA_UNUSED, LPARAM data)
56{
57 MONITORINFOEX mi;
58 Ecore_Win32_Monitor_Priv *ewm;
59 Eina_Bool is_added;
60
61 mi.cbSize = sizeof(MONITORINFOEX);
62 GetMonitorInfo(m, (MONITORINFO *)&mi);
63
64 if (data == 1)
65 {
66 Eina_List *l;
67
68 is_added = EINA_FALSE;
69 EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
70 {
71 if (strcmp(mi.szDevice, ewm->name) != 0)
72 {
73 is_added = EINA_TRUE;
74 break;
75 }
76 }
77 }
78 else if (data == 2)
79 {
80 Eina_List *l;
81
82 EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
83 {
84 if (strcmp(mi.szDevice, ewm->name) == 0)
85 {
86 ewm->delete_me = EINA_FALSE;
87 return FALSE;
88 }
89 }
90 }
91 else
92 is_added = EINA_TRUE;
93
94 if (!is_added)
95 return TRUE;
96
97 ewm = (Ecore_Win32_Monitor_Priv *)malloc(sizeof(Ecore_Win32_Monitor_Priv));
98 if (ewm)
99 {
100 ewm->monitor.desktop.x = mi.rcMonitor.left;
101 ewm->monitor.desktop.y = mi.rcMonitor.top;
102 ewm->monitor.desktop.w = mi.rcMonitor.right - mi.rcMonitor.left;
103 ewm->monitor.desktop.h = mi.rcMonitor.bottom - mi.rcMonitor.top;
104 if (!GetDpiForMonitor_ ||
105 (GetDpiForMonitor_(m, 0,
106 &ewm->monitor.dpi.x,
107 &ewm->monitor.dpi.y) != S_OK))
108 {
109 HDC dc;
110
111 dc = GetDC(NULL);
112 ewm->monitor.dpi.x = GetDeviceCaps(dc, LOGPIXELSX);
113 ewm->monitor.dpi.y = GetDeviceCaps(dc, LOGPIXELSY);
114 ReleaseDC(NULL, dc);
115 }
116 ewm->name = strdup(mi.szDevice);
117 if (ewm->name)
118 ecore_win32_monitors = eina_list_append(ecore_win32_monitors, ewm);
119 else
120 free(ewm);
121 }
122
123 return TRUE;
124}
125
126/**
127 * @endcond
128 */
129
130
131/*============================================================================*
132 * Global *
133 *============================================================================*/
134
135HWND ecore_win32_monitor_window = NULL;
136
137void
138ecore_win32_monitor_init(void)
139{
140 DEV_BROADCAST_DEVICEINTERFACE notification;
141 DWORD style;
142
143 style = WS_POPUP & ~(WS_CAPTION | WS_THICKFRAME);
144 ecore_win32_monitor_window = CreateWindow(ECORE_WIN32_WINDOW_CLASS, "",
145 style,
146 10, 10,
147 100, 100,
148 NULL, NULL,
149 _ecore_win32_instance, NULL);
150
151 if (ecore_win32_monitor_window)
152 {
153 ZeroMemory(&notification, sizeof(notification));
154 notification.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
155 notification.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
156 notification.dbcc_classguid = GUID_DEVINTERFACE_MONITOR;
157 RegisterDeviceNotification(ecore_win32_monitor_window,
158 &notification,
159 DEVICE_NOTIFY_WINDOW_HANDLE);
160 }
161
162 /*
163 * Even if RegisterDeviceNotification() fails, the next call will
164 * fill one item of the monitor lists, except if there is no more
165 * memory
166 */
167 ecore_win32_monitor_update(0);
168
169 _ecore_win32_mod = LoadLibrary("shcore.dll");
170 if (_ecore_win32_mod)
171 GetDpiForMonitor_ = (GetDpiForMonitor_t)GetProcAddress(_ecore_win32_mod,
172 "GetDpiForMonitor");
173}
174
175void
176ecore_win32_monitor_shutdown(void)
177{
178 Ecore_Win32_Monitor_Priv *ewm;
179
180 if (_ecore_win32_mod)
181 FreeLibrary(_ecore_win32_mod);
182 EINA_LIST_FREE(ecore_win32_monitors, ewm)
183 _ecore_win32_monitor_free(ewm);
184 if (ecore_win32_monitor_window)
185 DestroyWindow(ecore_win32_monitor_window);
186}
187
188void
189ecore_win32_monitor_update(int d)
190{
191 Ecore_Win32_Monitor_Priv *ewm;
192 Eina_List *l;
193
194 if (d == 2)
195 {
196 EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
197 ewm->delete_me = EINA_TRUE;
198 }
199
200 EnumDisplayMonitors(NULL, NULL, _ecore_win32_monitor_update_cb, d);
201
202 if (d == 2)
203 {
204 EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
205 {
206 if (ewm->delete_me == EINA_TRUE)
207 {
208 ecore_win32_monitors = eina_list_remove(ecore_win32_monitors, ewm);
209 _ecore_win32_monitor_free(ewm);
210 break;
211 }
212 }
213 }
214}
215
216/*============================================================================*
217 * API *
218 *============================================================================*/
219
220EAPI Eina_Iterator *
221ecore_win32_monitors_get(void)
222{
223 return eina_list_iterator_new(ecore_win32_monitors);
224}
diff --git a/src/lib/ecore_win32/ecore_win32_private.h b/src/lib/ecore_win32/ecore_win32_private.h
index bb22b466f5..1956f8bf6b 100644
--- a/src/lib/ecore_win32/ecore_win32_private.h
+++ b/src/lib/ecore_win32/ecore_win32_private.h
@@ -6,9 +6,6 @@
6extern "C" { 6extern "C" {
7#endif 7#endif
8 8
9/* logging messages macros */
10extern int _ecore_win32_log_dom_global;
11
12#ifdef ECORE_WIN32_DEFAULT_LOG_COLOR 9#ifdef ECORE_WIN32_DEFAULT_LOG_COLOR
13# undef ECORE_WIN32_DEFAULT_LOG_COLOR 10# undef ECORE_WIN32_DEFAULT_LOG_COLOR
14#endif 11#endif
@@ -134,12 +131,16 @@ struct _Ecore_Win32_Window
134}; 131};
135 132
136 133
134/* logging messages macros */
135extern int _ecore_win32_log_dom_global;
136
137extern HINSTANCE _ecore_win32_instance; 137extern HINSTANCE _ecore_win32_instance;
138extern double _ecore_win32_double_click_time; 138extern double _ecore_win32_double_click_time;
139extern unsigned long _ecore_win32_event_last_time; 139extern unsigned long _ecore_win32_event_last_time;
140extern Ecore_Win32_Window *_ecore_win32_event_last_window; 140extern Ecore_Win32_Window *_ecore_win32_event_last_window;
141extern Ecore_Win32_Cursor *_ecore_win32_cursor_x[77]; 141extern Ecore_Win32_Cursor *_ecore_win32_cursor_x[77];
142 142
143extern HWND ecore_win32_monitor_window;
143 144
144void _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg); 145void _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg);
145void _ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg); 146void _ecore_win32_event_handle_key_release(Ecore_Win32_Callback_Data *msg);
@@ -173,6 +174,10 @@ Eina_Bool ecore_win32_window_drag(Ecore_Win32_Window *w, int ptx, int pty);
173 174
174Ecore_Win32_Cursor *_ecore_win32_cursor_x11_shaped_new(Ecore_Win32_Cursor_X11_Shape shape); 175Ecore_Win32_Cursor *_ecore_win32_cursor_x11_shaped_new(Ecore_Win32_Cursor_X11_Shape shape);
175 176
177void ecore_win32_monitor_init(void);
178void ecore_win32_monitor_shutdown(void);
179void ecore_win32_monitor_update(int d);
180
176 181
177#ifdef __cplusplus 182#ifdef __cplusplus
178} 183}