Bug/glfw monitors update 210 (#214)

* Patch to resolve monitor change event is not get fired issue

* Fix monitors init on non Windows

* GLFW patch: create monitor dpi dependent cursor icons

* Update go-gl/glfw dep to point fork
This commit is contained in:
Max Risuhin 2019-02-14 18:46:23 +02:00 committed by Liam Galvin
parent 35193b7981
commit ab91b8079f
9 changed files with 209 additions and 19 deletions

3
Gopkg.lock generated
View File

@ -53,7 +53,8 @@
branch = "master"
name = "github.com/go-gl/glfw"
packages = ["v3.2/glfw"]
revision = "691ee1b84c51ae625ed1aafebc915d3db3d63d66"
revision = "14db69009976890a990c14b47a04a91621597f9b"
source = "github.com/MaxRis/glfw"
[[projects]]
name = "github.com/gobuffalo/envy"

View File

@ -32,6 +32,7 @@
[[constraint]]
branch = "master"
name = "github.com/go-gl/glfw"
source = "github.com/MaxRis/glfw"
[[constraint]]
name = "github.com/gobuffalo/packr"

View File

@ -130,7 +130,9 @@ GLFWAPI int glfwInit(void)
return GLFW_FALSE;
}
#ifndef _GLFW_WIN32
_glfw.monitors = _glfwPlatformGetMonitors(&_glfw.monitorCount);
#endif
_glfwInitialized = GLFW_TRUE;
_glfw.timerOffset = _glfwPlatformGetTimerValue();

View File

@ -48,6 +48,9 @@
#define GLFW_INCLUDE_NONE
#include "../include/GLFW/glfw3.h"
#define _GLFW_INSERT_FIRST 0
#define _GLFW_INSERT_LAST 1
typedef int GLFWbool;
typedef struct _GLFWwndconfig _GLFWwndconfig;
@ -398,6 +401,7 @@ struct _GLFWwindow
struct _GLFWmonitor
{
char* name;
void* userPointer;
// Physical dimensions in millimeters.
int widthMM, heightMM;
@ -922,6 +926,9 @@ void _glfwInputMonitorChange(void);
*/
void _glfwInputMonitorWindowChange(_GLFWmonitor* monitor, _GLFWwindow* window);
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
/*! @brief Notifies shared code of an error.
* @param[in] error The error code most suitable for the error.
* @param[in] format The `printf` style format string of the error

View File

@ -86,6 +86,71 @@ static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of a monitor connection or disconnection
//
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{
if (action == GLFW_CONNECTED)
{
_glfw.monitorCount++;
_glfw.monitors =
realloc(_glfw.monitors, sizeof(_GLFWmonitor*) * _glfw.monitorCount);
if (placement == _GLFW_INSERT_FIRST)
{
memmove(_glfw.monitors + 1,
_glfw.monitors,
(_glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
_glfw.monitors[0] = monitor;
}
else
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
}
else if (action == GLFW_DISCONNECTED)
{
int i;
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->monitor == monitor)
{
int width, height, xoff, yoff;
_glfwPlatformGetWindowSize(window, &width, &height);
_glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0);
_glfwPlatformGetWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_glfwPlatformSetWindowPos(window, xoff, yoff);
}
}
for (i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
{
_glfw.monitorCount--;
memmove(_glfw.monitors + i,
_glfw.monitors + i + 1,
(_glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
break;
}
}
}
if (_glfw.callbacks.monitor)
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
if (action == GLFW_DISCONNECTED)
_glfwFreeMonitor(monitor);
}
// Notifies shared code that a full screen window has acquired or released
// a monitor
//
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
{
monitor->window = window;
}
void _glfwInputMonitorChange(void)
{
int i, j, monitorCount = _glfw.monitorCount;

View File

@ -309,7 +309,7 @@ static HWND createHelperWindow(void)
L"GLFW helper window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1,
HWND_MESSAGE, NULL,
NULL, NULL,
GetModuleHandleW(NULL),
NULL);
if (!window)
@ -428,6 +428,7 @@ int _glfwPlatformInit(void)
_glfwInitTimerWin32();
_glfwInitJoysticksWin32();
_glfwPollMonitorsWin32();
return GLFW_TRUE;
}

View File

@ -146,6 +146,116 @@ void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsWin32(void)
{
int i, disconnectedCount;
_GLFWmonitor** disconnected = NULL;
DWORD adapterIndex, displayIndex;
DISPLAY_DEVICEW adapter, display;
_GLFWmonitor* monitor;
disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (adapterIndex = 0; ; adapterIndex++)
{
int type = _GLFW_INSERT_LAST;
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
type = _GLFW_INSERT_FIRST;
for (displayIndex = 0; ; displayIndex++)
{
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.displayName,
display.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, &display);
if (!monitor)
{
free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
type = _GLFW_INSERT_LAST;
}
// HACK: If an active adapter does not have any display devices
// (as sometimes happens), add it directly as a monitor
if (displayIndex == 0)
{
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.adapterName,
adapter.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, NULL);
if (!monitor)
{
free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
}
}
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
free(disconnected);
}
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
{
int found = 0;

View File

@ -64,6 +64,9 @@
// GLFW uses DirectInput8 interfaces
#define DIRECTINPUT_VERSION 0x0800
// Enable standard cursors images defines
#define OEMRESOURCE
#include <wctype.h>
#include <windows.h>
#include <mmsystem.h>
@ -344,6 +347,7 @@ char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
void _glfwInitTimerWin32(void);
void _glfwPollMonitorsWin32(void);
GLFWbool _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);

View File

@ -280,25 +280,25 @@ static void updateClipRect(_GLFWwindow* window)
// Translates a GLFW standard cursor to a resource ID
//
static LPWSTR translateCursorShape(int shape)
static int translateCursorShape(int shape)
{
switch (shape)
{
case GLFW_ARROW_CURSOR:
return IDC_ARROW;
return OCR_NORMAL;
case GLFW_IBEAM_CURSOR:
return IDC_IBEAM;
return OCR_IBEAM;
case GLFW_CROSSHAIR_CURSOR:
return IDC_CROSS;
return OCR_CROSS;
case GLFW_HAND_CURSOR:
return IDC_HAND;
return OCR_HAND;
case GLFW_HRESIZE_CURSOR:
return IDC_SIZEWE;
return OCR_SIZEWE;
case GLFW_VRESIZE_CURSOR:
return IDC_SIZENS;
return OCR_SIZENS;
}
return NULL;
return 0;
}
// Retrieves and translates modifier keys
@ -405,7 +405,7 @@ static GLFWbool acquireMonitor(_GLFWwindow* window)
xpos, ypos, mode.width, mode.height,
SWP_NOACTIVATE | SWP_NOCOPYBITS);
_glfwInputMonitorWindowChange(window->monitor, window);
_glfwInputMonitorWindow(window->monitor, window);
return status;
}
@ -416,7 +416,7 @@ static void releaseMonitor(_GLFWwindow* window)
if (window->monitor->window != window)
return;
_glfwInputMonitorWindowChange(window->monitor, NULL);
_glfwInputMonitorWindow(window->monitor, NULL);
_glfwRestoreVideoModeWin32(window->monitor);
}
@ -432,14 +432,12 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
switch (uMsg)
{
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
case WM_DEVICECHANGE:
{
if (wParam == DBT_DEVNODES_CHANGED)
{
_glfwInputMonitorChange();
return TRUE;
}
else if (wParam == DBT_DEVICEARRIVAL)
if (wParam == DBT_DEVICEARRIVAL)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh)
@ -1525,7 +1523,8 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor,
int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape)
{
cursor->win32.handle =
CopyCursor(LoadCursorW(NULL, translateCursorShape(shape)));
(HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(translateCursorShape(shape)), IMAGE_CURSOR,
0, 0, LR_DEFAULTSIZE | LR_SHARED);
if (!cursor->win32.handle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,