forked from enlightenment/efl
Ecore_Win32: add API to retrieve the geometry and dpi of plugged displays
@feature Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
parent
122c34b2ce
commit
449b2a4bf3
|
@ -18,6 +18,7 @@ lib/ecore_win32/ecore_win32_dnd_data_object.cpp \
|
|||
lib/ecore_win32/ecore_win32_dnd_drop_source.cpp \
|
||||
lib/ecore_win32/ecore_win32_dnd_drop_target.cpp \
|
||||
lib/ecore_win32/ecore_win32_event.c \
|
||||
lib/ecore_win32/ecore_win32_monitor.c \
|
||||
lib/ecore_win32/ecore_win32_window.c \
|
||||
lib/ecore_win32/ecore_win32_private.h \
|
||||
lib/ecore_win32/ecore_win32_cursor_x11.h \
|
||||
|
|
|
@ -740,6 +740,35 @@ EAPI Eina_Bool ecore_win32_clipboard_get(const Ecore_Win32_Window *window,
|
|||
*/
|
||||
EAPI Eina_Bool ecore_win32_clipboard_clear(const Ecore_Win32_Window *window);
|
||||
|
||||
/**
|
||||
* @typedef Ecore_Win32_Monitor
|
||||
* Desktop geometry and dpi of a monitor.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
Eina_Rectangle desktop; /**< Coordinates and size of the desktop */
|
||||
struct
|
||||
{
|
||||
unsigned int x; /**< DPI along the X axis */
|
||||
unsigned int y; /**< DPI along the Y axis */
|
||||
} dpi;
|
||||
} Ecore_Win32_Monitor;
|
||||
|
||||
/**
|
||||
* @brief Return the coordinates, sizes DPI's of the monitors.
|
||||
*
|
||||
* @return An iterator of an Eina list, with #Ecore_Win32_Monitor
|
||||
* as data.
|
||||
*
|
||||
* This function returns the coordinates, sizes and DPI's of the
|
||||
* monitors as an iterator of a list of #Ecore_Win32_Monitor.
|
||||
*
|
||||
* @since 1.20
|
||||
*/
|
||||
EAPI Eina_Iterator *ecore_win32_monitors_get(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <windowsx.h>
|
||||
#include <dbt.h>
|
||||
|
||||
#include <Eina.h>
|
||||
#include <Ecore.h>
|
||||
|
@ -209,6 +210,7 @@ _ecore_win32_window_procedure(HWND window,
|
|||
efl_AddClipboardFormatListener acfl;
|
||||
|
||||
INF("create window message");
|
||||
|
||||
acfl = (efl_AddClipboardFormatListener)GetProcAddress(GetModuleHandle("user32.dll"),
|
||||
"AddClipboardFormatListener");
|
||||
if (acfl)
|
||||
|
@ -386,6 +388,20 @@ _ecore_win32_window_procedure(HWND window,
|
|||
case WM_SYNCPAINT:
|
||||
INF("sync paint message");
|
||||
return 0;
|
||||
/* Desktop notifications */
|
||||
case WM_DEVICECHANGE:
|
||||
if (window == ecore_win32_monitor_window)
|
||||
{
|
||||
PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)data_param;
|
||||
|
||||
if ((window_param == DBT_DEVICEARRIVAL) &&
|
||||
(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
|
||||
ecore_win32_monitor_update(1);
|
||||
|
||||
if ((window_param == DBT_DEVICEREMOVECOMPLETE) &&
|
||||
(pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE))
|
||||
ecore_win32_monitor_update(2);
|
||||
}
|
||||
default:
|
||||
return DefWindowProc(window, message, window_param, data_param);
|
||||
}
|
||||
|
@ -578,6 +594,8 @@ ecore_win32_init()
|
|||
for (i = 0; i < 77; i++)
|
||||
_ecore_win32_cursor_x[i] = _ecore_win32_cursor_x11_shaped_new(i);
|
||||
|
||||
ecore_win32_monitor_init();
|
||||
|
||||
return _ecore_win32_init_count;
|
||||
|
||||
unregister_class:
|
||||
|
@ -612,6 +630,8 @@ ecore_win32_shutdown()
|
|||
if (--_ecore_win32_init_count != 0)
|
||||
return _ecore_win32_init_count;
|
||||
|
||||
ecore_win32_monitor_shutdown();
|
||||
|
||||
for (i = 0; i < 77; i++)
|
||||
ecore_win32_cursor_free(_ecore_win32_cursor_x[i]);
|
||||
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#undef WIN32_LEAN_AND_MEAN
|
||||
#include <dbt.h>
|
||||
|
||||
#include <Eina.h>
|
||||
|
||||
#include "Ecore_Win32.h"
|
||||
#include "ecore_win32_private.h"
|
||||
|
||||
/*============================================================================*
|
||||
* Local *
|
||||
*============================================================================*/
|
||||
|
||||
/**
|
||||
* @cond LOCAL
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Ecore_Win32_Monitor monitor;
|
||||
char *name;
|
||||
Eina_Bool delete_me : 1;
|
||||
} Ecore_Win32_Monitor_Priv;
|
||||
|
||||
typedef HRESULT (WINAPI *GetDpiForMonitor_t)(HMONITOR, int, UINT *, UINT *);
|
||||
|
||||
static HMODULE _ecore_win32_mod = NULL;
|
||||
static GetDpiForMonitor_t GetDpiForMonitor_ = NULL;
|
||||
static Eina_List *ecore_win32_monitors = NULL;
|
||||
|
||||
#ifndef GUID_DEVINTERFACE_MONITOR
|
||||
static GUID GUID_DEVINTERFACE_MONITOR = {0xe6f07b5f, 0xee97, 0x4a90, { 0xb0, 0x76, 0x33, 0xf5, 0x7b, 0xf4, 0xea, 0xa7} };
|
||||
#endif
|
||||
|
||||
static void
|
||||
_ecore_win32_monitor_free(void *p)
|
||||
{
|
||||
Ecore_Win32_Monitor_Priv *ewm = p;
|
||||
|
||||
if (ewm)
|
||||
{
|
||||
free(ewm->name);
|
||||
free(ewm);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CALLBACK
|
||||
_ecore_win32_monitor_update_cb(HMONITOR m, HDC monitor EINA_UNUSED, LPRECT r EINA_UNUSED, LPARAM data)
|
||||
{
|
||||
MONITORINFOEX mi;
|
||||
Ecore_Win32_Monitor_Priv *ewm;
|
||||
Eina_Bool is_added;
|
||||
|
||||
mi.cbSize = sizeof(MONITORINFOEX);
|
||||
GetMonitorInfo(m, (MONITORINFO *)&mi);
|
||||
|
||||
if (data == 1)
|
||||
{
|
||||
Eina_List *l;
|
||||
|
||||
is_added = EINA_FALSE;
|
||||
EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
|
||||
{
|
||||
if (strcmp(mi.szDevice, ewm->name) != 0)
|
||||
{
|
||||
is_added = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data == 2)
|
||||
{
|
||||
Eina_List *l;
|
||||
|
||||
EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
|
||||
{
|
||||
if (strcmp(mi.szDevice, ewm->name) == 0)
|
||||
{
|
||||
ewm->delete_me = EINA_FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
is_added = EINA_TRUE;
|
||||
|
||||
if (!is_added)
|
||||
return TRUE;
|
||||
|
||||
ewm = (Ecore_Win32_Monitor_Priv *)malloc(sizeof(Ecore_Win32_Monitor_Priv));
|
||||
if (ewm)
|
||||
{
|
||||
ewm->monitor.desktop.x = mi.rcMonitor.left;
|
||||
ewm->monitor.desktop.y = mi.rcMonitor.top;
|
||||
ewm->monitor.desktop.w = mi.rcMonitor.right - mi.rcMonitor.left;
|
||||
ewm->monitor.desktop.h = mi.rcMonitor.bottom - mi.rcMonitor.top;
|
||||
if (!GetDpiForMonitor_ ||
|
||||
(GetDpiForMonitor_(m, 0,
|
||||
&ewm->monitor.dpi.x,
|
||||
&ewm->monitor.dpi.y) != S_OK))
|
||||
{
|
||||
HDC dc;
|
||||
|
||||
dc = GetDC(NULL);
|
||||
ewm->monitor.dpi.x = GetDeviceCaps(dc, LOGPIXELSX);
|
||||
ewm->monitor.dpi.y = GetDeviceCaps(dc, LOGPIXELSY);
|
||||
ReleaseDC(NULL, dc);
|
||||
}
|
||||
ewm->name = strdup(mi.szDevice);
|
||||
if (ewm->name)
|
||||
ecore_win32_monitors = eina_list_append(ecore_win32_monitors, ewm);
|
||||
else
|
||||
free(ewm);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
|
||||
/*============================================================================*
|
||||
* Global *
|
||||
*============================================================================*/
|
||||
|
||||
HWND ecore_win32_monitor_window = NULL;
|
||||
|
||||
void
|
||||
ecore_win32_monitor_init(void)
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE notification;
|
||||
DWORD style;
|
||||
|
||||
style = WS_POPUP & ~(WS_CAPTION | WS_THICKFRAME);
|
||||
ecore_win32_monitor_window = CreateWindow(ECORE_WIN32_WINDOW_CLASS, "",
|
||||
style,
|
||||
10, 10,
|
||||
100, 100,
|
||||
NULL, NULL,
|
||||
_ecore_win32_instance, NULL);
|
||||
|
||||
if (ecore_win32_monitor_window)
|
||||
{
|
||||
ZeroMemory(¬ification, sizeof(notification));
|
||||
notification.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
|
||||
notification.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
notification.dbcc_classguid = GUID_DEVINTERFACE_MONITOR;
|
||||
RegisterDeviceNotification(ecore_win32_monitor_window,
|
||||
¬ification,
|
||||
DEVICE_NOTIFY_WINDOW_HANDLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Even if RegisterDeviceNotification() fails, the next call will
|
||||
* fill one item of the monitor lists, except if there is no more
|
||||
* memory
|
||||
*/
|
||||
ecore_win32_monitor_update(0);
|
||||
|
||||
_ecore_win32_mod = LoadLibrary("shcore.dll");
|
||||
if (_ecore_win32_mod)
|
||||
GetDpiForMonitor_ = (GetDpiForMonitor_t)GetProcAddress(_ecore_win32_mod,
|
||||
"GetDpiForMonitor");
|
||||
}
|
||||
|
||||
void
|
||||
ecore_win32_monitor_shutdown(void)
|
||||
{
|
||||
Ecore_Win32_Monitor_Priv *ewm;
|
||||
|
||||
if (_ecore_win32_mod)
|
||||
FreeLibrary(_ecore_win32_mod);
|
||||
EINA_LIST_FREE(ecore_win32_monitors, ewm)
|
||||
_ecore_win32_monitor_free(ewm);
|
||||
if (ecore_win32_monitor_window)
|
||||
DestroyWindow(ecore_win32_monitor_window);
|
||||
}
|
||||
|
||||
void
|
||||
ecore_win32_monitor_update(int d)
|
||||
{
|
||||
Ecore_Win32_Monitor_Priv *ewm;
|
||||
Eina_List *l;
|
||||
|
||||
if (d == 2)
|
||||
{
|
||||
EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
|
||||
ewm->delete_me = EINA_TRUE;
|
||||
}
|
||||
|
||||
EnumDisplayMonitors(NULL, NULL, _ecore_win32_monitor_update_cb, d);
|
||||
|
||||
if (d == 2)
|
||||
{
|
||||
EINA_LIST_FOREACH(ecore_win32_monitors, l, ewm)
|
||||
{
|
||||
if (ewm->delete_me == EINA_TRUE)
|
||||
{
|
||||
ecore_win32_monitors = eina_list_remove(ecore_win32_monitors, ewm);
|
||||
_ecore_win32_monitor_free(ewm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
*============================================================================*/
|
||||
|
||||
EAPI Eina_Iterator *
|
||||
ecore_win32_monitors_get(void)
|
||||
{
|
||||
return eina_list_iterator_new(ecore_win32_monitors);
|
||||
}
|
|
@ -6,9 +6,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* logging messages macros */
|
||||
extern int _ecore_win32_log_dom_global;
|
||||
|
||||
#ifdef ECORE_WIN32_DEFAULT_LOG_COLOR
|
||||
# undef ECORE_WIN32_DEFAULT_LOG_COLOR
|
||||
#endif
|
||||
|
@ -134,12 +131,16 @@ struct _Ecore_Win32_Window
|
|||
};
|
||||
|
||||
|
||||
/* logging messages macros */
|
||||
extern int _ecore_win32_log_dom_global;
|
||||
|
||||
extern HINSTANCE _ecore_win32_instance;
|
||||
extern double _ecore_win32_double_click_time;
|
||||
extern unsigned long _ecore_win32_event_last_time;
|
||||
extern Ecore_Win32_Window *_ecore_win32_event_last_window;
|
||||
extern Ecore_Win32_Cursor *_ecore_win32_cursor_x[77];
|
||||
|
||||
extern HWND ecore_win32_monitor_window;
|
||||
|
||||
void _ecore_win32_event_handle_key_press(Ecore_Win32_Callback_Data *msg);
|
||||
void _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);
|
|||
|
||||
Ecore_Win32_Cursor *_ecore_win32_cursor_x11_shaped_new(Ecore_Win32_Cursor_X11_Shape shape);
|
||||
|
||||
void ecore_win32_monitor_init(void);
|
||||
void ecore_win32_monitor_shutdown(void);
|
||||
void ecore_win32_monitor_update(int d);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue