Merge branch 'master' into blender2.8

Conflicts:
	source/blender/blenloader/intern/readfile.c
	source/blender/windowmanager/intern/wm_window.c
This commit is contained in:
Bastien Montagne
2017-03-28 10:41:10 +02:00
73 changed files with 1419 additions and 698 deletions

View File

@@ -907,6 +907,11 @@ extern int GHOST_UseNativePixels(void);
*/
extern float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle);
/**
* Returns the suggested DPI for this window.
*/
extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle);
/**
* Enable IME attached to the given window, i.e. allows user-input
* events to be dispatched to the IME.

View File

@@ -332,6 +332,12 @@ public:
virtual float getNativePixelSize(void) = 0;
/**
* Returns the recommended DPI for this window.
* \return The recommended DPI for this window.
*/
virtual GHOST_TUns16 getDPIHint() = 0;
#ifdef WITH_INPUT_IME
/**
* Enable IME attached to the given window, i.e. allows user-input

View File

@@ -189,6 +189,7 @@ typedef enum {
GHOST_kEventWindowUpdate,
GHOST_kEventWindowSize,
GHOST_kEventWindowMove,
GHOST_kEventWindowDPIHintChanged,
GHOST_kEventDraggingEntered,
GHOST_kEventDraggingUpdated,

View File

@@ -914,6 +914,12 @@ float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
return 1.0f;
}
GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
return window->getDPIHint();
}
#ifdef WITH_INPUT_IME
void GHOST_BeginIME(GHOST_WindowHandle windowhandle,

View File

@@ -111,6 +111,11 @@
#define VK_MEDIA_PLAY_PAUSE 0xB3
#endif // VK_MEDIA_PLAY_PAUSE
// Window message newer than Windows 7
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif // WM_DPICHANGED
/* Workaround for some laptop touchpads, some of which seems to
* have driver issues which makes it so window function receives
* the message, but PeekMessage doesn't pick those messages for
@@ -152,6 +157,27 @@ static void initRawInput()
#undef DEVICE_COUNT
}
#ifndef DPI_ENUMS_DECLARED
typedef enum PROCESS_DPI_AWARENESS {
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
#define USER_DEFAULT_SCREEN_DPI 96
#define DPI_ENUMS_DECLARED
#endif
typedef HRESULT(API * GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
typedef BOOL(API * GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
GHOST_SystemWin32::GHOST_SystemWin32()
: m_hasPerformanceCounter(false), m_freq(0), m_start(0)
{
@@ -161,6 +187,18 @@ GHOST_SystemWin32::GHOST_SystemWin32()
m_consoleStatus = 1;
// Tell Windows we are per monitor DPI aware. This disables the default
// blurry scaling and enables WM_DPICHANGED to allow us to draw at proper DPI.
HMODULE m_shcore = ::LoadLibrary("Shcore.dll");
if (m_shcore) {
GHOST_WIN32_SetProcessDpiAwareness fpSetProcessDpiAwareness =
(GHOST_WIN32_SetProcessDpiAwareness) ::GetProcAddress(m_shcore, "SetProcessDpiAwareness");
if (fpSetProcessDpiAwareness) {
fpSetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
}
}
// Check if current keyboard layout uses AltGr and save keylayout ID for
// specialized handling if keys like VK_OEM_*. I.e. french keylayout
// generates VK_OEM_8 for their exclamation key (key left of right shift)
@@ -922,6 +960,20 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
GHOST_ASSERT(system, "GHOST_SystemWin32::s_wndProc(): system not initialized");
if (hwnd) {
if(msg == WM_NCCREATE) {
// Tell Windows to automatically handle scaling of non-client areas
// such as the caption bar. EnableNonClientDpiScaling was introduced in Windows 10
HMODULE m_user32 = ::LoadLibrary("User32.dll");
if (m_user32) {
GHOST_WIN32_EnableNonClientDpiScaling fpEnableNonClientDpiScaling =
(GHOST_WIN32_EnableNonClientDpiScaling) ::GetProcAddress(m_user32, "EnableNonClientDpiScaling");
if (fpEnableNonClientDpiScaling) {
fpEnableNonClientDpiScaling(hwnd);
}
}
}
GHOST_WindowWin32 *window = (GHOST_WindowWin32 *)::GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (window) {
switch (msg) {
@@ -1293,6 +1345,32 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
event = processWindowEvent(GHOST_kEventWindowMove, window);
}
break;
case WM_DPICHANGED:
/* The WM_DPICHANGED message is sent when the effective dots per inch (dpi) for a window has changed.
* The DPI is the scale factor for a window. There are multiple events that can cause the DPI to
* change such as when the window is moved to a monitor with a different DPI.
*/
{
WORD newYAxisDPI = HIWORD(wParam);
WORD newXAxisDPI = LOWORD(wParam);
// The suggested new size and position of the window.
RECT* const suggestedWindowRect = (RECT*)lParam;
// Push DPI change event first
system->pushEvent(processWindowEvent(GHOST_kEventWindowDPIHintChanged, window));
system->dispatchEvents();
eventHandled = true;
// Then move and resize window
SetWindowPos(hwnd,
NULL,
suggestedWindowRect->left,
suggestedWindowRect->top,
suggestedWindowRect->right - suggestedWindowRect->left,
suggestedWindowRect->bottom - suggestedWindowRect->top,
SWP_NOZORDER | SWP_NOACTIVATE);
}
break;
////////////////////////////////////////////////////////////////////////
// Window events, ignored

View File

@@ -295,6 +295,15 @@ public:
return 1.0f;
}
/**
* Returns the recommended DPI for this window.
* \return The recommended DPI for this window.
*/
virtual inline GHOST_TUns16 getDPIHint()
{
return 96;
}
#ifdef WITH_INPUT_IME
virtual void beginIME(GHOST_TInt32 x,
GHOST_TInt32 y,

View File

@@ -563,3 +563,19 @@ GHOST_WindowSDL::setWindowCursorVisibility(bool visible)
SDL_ShowCursor(visible);
return GHOST_kSuccess;
}
GHOST_TUns16
GHOST_WindowSDL::getDPIHint()
{
int displayIndex = SDL_GetWindowDisplayIndex(m_sdl_win);
if (displayIndex < 0) {
return 96;
}
float ddpi;
if (SDL_GetDisplayDPI(displayIndex, &ddpi, NULL, NULL) != 0) {
return 96;
}
return (int)ddpi;
}

View File

@@ -168,6 +168,8 @@ protected:
GHOST_TSuccess beginFullScreen() const { return GHOST_kFailure; }
GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
GHOST_TUns16 getDPIHint();
};

View File

@@ -92,6 +92,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
m_tablet(0),
m_maxPressure(0),
m_normal_state(GHOST_kWindowStateNormal),
m_user32(NULL),
m_parentWindowHwnd(parentwindowhwnd),
m_debug_context(is_debug)
{
@@ -905,6 +906,23 @@ void GHOST_WindowWin32::bringTabletContextToFront()
}
}
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
{
if (!m_user32) {
m_user32 = ::LoadLibrary("user32.dll");
}
if (m_user32) {
GHOST_WIN32_GetDpiForWindow fpGetDpiForWindow = (GHOST_WIN32_GetDpiForWindow) ::GetProcAddress(m_user32, "GetDpiForWindow");
if (fpGetDpiForWindow) {
return fpGetDpiForWindow(this->m_hWnd);
}
}
return USER_DEFAULT_SCREEN_DPI;
}
/** Reverse the bits in a GHOST_TUns8 */
static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
{

View File

@@ -58,6 +58,12 @@ typedef BOOL (API * GHOST_WIN32_WTClose)(HCTX);
typedef BOOL (API * GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
typedef BOOL (API * GHOST_WIN32_WTOverlap)(HCTX, BOOL);
// typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
typedef UINT(API * GHOST_WIN32_GetDpiForWindow)(HWND);
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif // USER_DEFAULT_SCREEN_DPI
/**
* GHOST window on M$ Windows OSs.
* \author Maarten Gribnau
@@ -251,6 +257,8 @@ public:
GHOST_TSuccess endFullScreen() const {return GHOST_kFailure;}
GHOST_TUns16 getDPIHint() override;
/** if the window currently resizing */
bool m_inLiveResize;
@@ -351,6 +359,9 @@ private:
GHOST_TWindowState m_normal_state;
/** user32 dll handle*/
HMODULE m_user32;
/** Hwnd to parent window */
GHOST_TEmbedderWindowID m_parentWindowHwnd;

View File

@@ -56,6 +56,9 @@
# include <X11/extensions/XInput2.h>
#endif
//For DPI value
#include <X11/Xresource.h>
#if defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__) || defined(_AIX)
# include <strings.h>
#endif
@@ -68,6 +71,7 @@
#include <algorithm>
#include <string>
#include <math.h>
/* For obscure full screen mode stuff
* lifted verbatim from blut. */
@@ -1661,3 +1665,44 @@ endFullScreen() const
return GHOST_kSuccess;
}
GHOST_TUns16
GHOST_WindowX11::
getDPIHint()
{
/* Try to read DPI setting set using xrdb */
char* resMan = XResourceManagerString(m_display);
if (resMan) {
XrmDatabase xrdb = XrmGetStringDatabase(resMan);
if (xrdb) {
char* type = NULL;
XrmValue val;
int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
if (success && type) {
if (strcmp(type, "String") == 0) {
return atoi((char*)val.addr);
}
}
}
}
/* Fallback to calculating DPI using X reported DPI, set using xrandr --dpi */
XWindowAttributes attr;
if (!XGetWindowAttributes(m_display, m_window, &attr)) {
/* Failed to get window attributes, return X11 default DPI */
return 96;
}
Screen* screen = attr.screen;
int pixelWidth = WidthOfScreen(screen);
int pixelHeight = HeightOfScreen(screen);
int mmWidth = WidthMMOfScreen(screen);
int mmHeight = HeightMMOfScreen(screen);
double pixelDiagonal = sqrt((pixelWidth * pixelWidth) + (pixelHeight * pixelHeight));
double mmDiagonal = sqrt((mmWidth * mmWidth) + (mmHeight * mmHeight));
float inchDiagonal = mmDiagonal * 0.039f;
int dpi = pixelDiagonal / inchDiagonal;
return dpi;
}

View File

@@ -235,6 +235,8 @@ public:
GHOST_TSuccess endFullScreen() const;
GHOST_TUns16 getDPIHint();
protected:
/**
* \param type The type of rendering context create.