parent
973bf29622
commit
4e96e90f64
@ -191,6 +191,7 @@ information on what to include when reporting a bug.
|
|||||||
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
- Bugfix: Invalid library paths were used in test and example CMake files (#930)
|
||||||
- Bugfix: The scancode for synthetic key release events was always zero
|
- Bugfix: The scancode for synthetic key release events was always zero
|
||||||
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
|
- Bugfix: The generated Doxyfile did not handle paths with spaces (#1081)
|
||||||
|
- [Win32] Added `glfwAttachWin32Window` for wrapping an existing `HWND` (#25)
|
||||||
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
- [Win32] Added system error strings to relevant GLFW error descriptions (#733)
|
||||||
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
- [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125)
|
||||||
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
- [Win32] Removed XInput circular deadzone from joystick axis data (#1045)
|
||||||
|
@ -172,6 +172,34 @@ GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
|||||||
* @ingroup native
|
* @ingroup native
|
||||||
*/
|
*/
|
||||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||||
|
|
||||||
|
/*! @brief Wraps an existing `HWND` in a new GLFW window object.
|
||||||
|
*
|
||||||
|
* This function creates a GLFW window object and its associated OpenGL or
|
||||||
|
* OpenGL ES context for an existing `HWND`. The `HWND` is not destroyed by
|
||||||
|
* GLFW.
|
||||||
|
*
|
||||||
|
* @param[in] handle The `HWND` to attach to the window object.
|
||||||
|
* @param[in] share The window whose context to share resources with, or `NULL`
|
||||||
|
* to not share resources.
|
||||||
|
* @return The handle of the created window, or `NULL` if an
|
||||||
|
* [error](@ref error_handling) occurred.
|
||||||
|
*
|
||||||
|
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||||
|
* GLFW_INVALID_ENUM, @ref GLFW_INVALID_VALUE, @ref GLFW_API_UNAVAILABLE, @ref
|
||||||
|
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE and @ref
|
||||||
|
* GLFW_PLATFORM_ERROR.
|
||||||
|
*
|
||||||
|
* @thread_safety This function may be called from any thread.
|
||||||
|
*
|
||||||
|
* @sa @ref window_creation
|
||||||
|
* @sa @ref glfwCreateWindow
|
||||||
|
*
|
||||||
|
* @since Added in version 3.3.
|
||||||
|
*
|
||||||
|
* @ingroup native
|
||||||
|
*/
|
||||||
|
GLFWAPI GLFWwindow* glfwAttachWin32Window(HWND handle, GLFWwindow* share);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||||
|
@ -272,6 +272,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
GLFWbool maximized;
|
GLFWbool maximized;
|
||||||
// Whether to enable framebuffer transparency on DWM
|
// Whether to enable framebuffer transparency on DWM
|
||||||
GLFWbool transparent;
|
GLFWbool transparent;
|
||||||
|
GLFWbool external;
|
||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
@ -1261,7 +1261,7 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window)
|
|||||||
if (_glfw.win32.disabledCursorWindow == window)
|
if (_glfw.win32.disabledCursorWindow == window)
|
||||||
_glfw.win32.disabledCursorWindow = NULL;
|
_glfw.win32.disabledCursorWindow = NULL;
|
||||||
|
|
||||||
if (window->win32.handle)
|
if (window->win32.handle && !window->win32.external)
|
||||||
{
|
{
|
||||||
RemovePropW(window->win32.handle, L"GLFW");
|
RemovePropW(window->win32.handle, L"GLFW");
|
||||||
DestroyWindow(window->win32.handle);
|
DestroyWindow(window->win32.handle);
|
||||||
@ -1998,3 +1998,102 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* handle)
|
|||||||
return window->win32.handle;
|
return window->win32.handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLFWAPI GLFWwindow* glfwAttachWin32Window(HWND handle, GLFWwindow* share)
|
||||||
|
{
|
||||||
|
_GLFWfbconfig fbconfig;
|
||||||
|
_GLFWctxconfig ctxconfig;
|
||||||
|
_GLFWwndconfig wndconfig;
|
||||||
|
_GLFWwindow* window;
|
||||||
|
|
||||||
|
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||||
|
|
||||||
|
fbconfig = _glfw.hints.framebuffer;
|
||||||
|
ctxconfig = _glfw.hints.context;
|
||||||
|
wndconfig = _glfw.hints.window;
|
||||||
|
|
||||||
|
ctxconfig.share = (_GLFWwindow*) share;
|
||||||
|
if (ctxconfig.share)
|
||||||
|
{
|
||||||
|
if (ctxconfig.client == GLFW_NO_API ||
|
||||||
|
ctxconfig.share->context.client == GLFW_NO_API)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_glfwIsValidContextConfig(&ctxconfig))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
window = calloc(1, sizeof(_GLFWwindow));
|
||||||
|
window->next = _glfw.windowListHead;
|
||||||
|
_glfw.windowListHead = window;
|
||||||
|
|
||||||
|
window->autoIconify = wndconfig.autoIconify;
|
||||||
|
window->cursorMode = GLFW_CURSOR_NORMAL;
|
||||||
|
|
||||||
|
window->minwidth = GLFW_DONT_CARE;
|
||||||
|
window->minheight = GLFW_DONT_CARE;
|
||||||
|
window->maxwidth = GLFW_DONT_CARE;
|
||||||
|
window->maxheight = GLFW_DONT_CARE;
|
||||||
|
window->numer = GLFW_DONT_CARE;
|
||||||
|
window->denom = GLFW_DONT_CARE;
|
||||||
|
|
||||||
|
window->win32.handle = handle;
|
||||||
|
window->win32.external = GLFW_TRUE;
|
||||||
|
|
||||||
|
SetPropW(window->win32.handle, L"GLFW", window);
|
||||||
|
SetWindowLongPtrW(window->win32.handle, GWLP_WNDPROC, (LONG_PTR) windowProc);
|
||||||
|
|
||||||
|
{
|
||||||
|
const DWORD style = GetWindowLongW(window->win32.handle, GWL_STYLE);
|
||||||
|
const DWORD exStyle = GetWindowLongW(window->win32.handle, GWL_EXSTYLE);
|
||||||
|
|
||||||
|
if (style & WS_THICKFRAME)
|
||||||
|
window->resizable = GLFW_TRUE;
|
||||||
|
if (style & (WS_BORDER | WS_THICKFRAME))
|
||||||
|
window->decorated = GLFW_TRUE;
|
||||||
|
if (exStyle & WS_EX_TOPMOST)
|
||||||
|
window->floating = GLFW_TRUE;
|
||||||
|
|
||||||
|
window->win32.maximized = IsZoomed(window->win32.handle);
|
||||||
|
window->win32.iconified = IsIconic(window->win32.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig.client != GLFW_NO_API)
|
||||||
|
{
|
||||||
|
if (ctxconfig.source == GLFW_NATIVE_CONTEXT_API)
|
||||||
|
{
|
||||||
|
if (!_glfwInitWGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (!_glfwCreateContextWGL(window, &ctxconfig, &fbconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
else if (ctxconfig.source == GLFW_EGL_CONTEXT_API)
|
||||||
|
{
|
||||||
|
if (!_glfwInitEGL())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (!_glfwCreateContextEGL(window, &ctxconfig, &fbconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
else if (ctxconfig.source == GLFW_OSMESA_CONTEXT_API)
|
||||||
|
{
|
||||||
|
if (!_glfwInitOSMesa())
|
||||||
|
return GLFW_FALSE;
|
||||||
|
if (!_glfwCreateContextOSMesa(window, &ctxconfig, &fbconfig))
|
||||||
|
return GLFW_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxconfig.client != GLFW_NO_API)
|
||||||
|
{
|
||||||
|
if (!_glfwRefreshContextAttribs(window, &ctxconfig))
|
||||||
|
{
|
||||||
|
glfwDestroyWindow((GLFWwindow*) window);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GLFWwindow*) window;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,12 @@ add_executable(timeout WIN32 MACOSX_BUNDLE timeout.c ${GLAD})
|
|||||||
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD})
|
add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD})
|
||||||
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD})
|
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${GETOPT} ${GLAD})
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
add_executable(native WIN32 native.c ${GLAD})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "This branch only makes sense on Win32 at the moment")
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(empty "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}")
|
target_link_libraries(threads "${CMAKE_THREAD_LIBS_INIT}")
|
||||||
if (RT_LIBRARY)
|
if (RT_LIBRARY)
|
||||||
@ -46,7 +52,7 @@ if (RT_LIBRARY)
|
|||||||
target_link_libraries(threads "${RT_LIBRARY}")
|
target_link_libraries(threads "${RT_LIBRARY}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(WINDOWS_BINARIES empty gamma icon inputlag joysticks opacity tearing
|
set(WINDOWS_BINARIES empty gamma icon inputlag joysticks native opacity tearing
|
||||||
threads timeout title windows)
|
threads timeout title windows)
|
||||||
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
set(CONSOLE_BINARIES clipboard events msaa glfwinfo iconify monitors reopen
|
||||||
cursor)
|
cursor)
|
||||||
|
116
tests/native.c
Normal file
116
tests/native.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
//========================================================================
|
||||||
|
// Win32 native handle attachment test
|
||||||
|
// Copyright (c) Camilla Löwy <elmindreda@glfw.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#define UNICODE
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
|
#include <GLFW/glfw3native.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void error_callback(int error, const char* description)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
// This will only be used until glfwAttachWin32Window
|
||||||
|
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
GLFWwindow* window;
|
||||||
|
WNDCLASSEX wc;
|
||||||
|
HWND handle;
|
||||||
|
|
||||||
|
ZeroMemory(&wc, sizeof(wc));
|
||||||
|
wc.cbSize = sizeof(wc);
|
||||||
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
||||||
|
wc.lpfnWndProc = (WNDPROC) windowProc;
|
||||||
|
wc.hInstance = GetModuleHandleW(NULL);
|
||||||
|
wc.hCursor = LoadCursorW(NULL, IDC_ARROW);
|
||||||
|
wc.lpszClassName = L"SomeKindOfWindowClassName";
|
||||||
|
|
||||||
|
if (!RegisterClassExW(&wc))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
handle = CreateWindowExW(WS_EX_APPWINDOW,
|
||||||
|
L"SomeKindOfWindowClassName",
|
||||||
|
L"HWND attachment test",
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
|
600, 400,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
GetModuleHandleW(NULL),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (!handle)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
|
||||||
|
if (!glfwInit())
|
||||||
|
{
|
||||||
|
DestroyWindow(handle);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
window = glfwAttachWin32Window(handle, NULL);
|
||||||
|
if (!window)
|
||||||
|
{
|
||||||
|
glfwTerminate();
|
||||||
|
DestroyWindow(handle);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
gladLoadGLLoader((GLADloadproc) glfwGetProcAddress);
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
|
||||||
|
while (!glfwWindowShouldClose(window))
|
||||||
|
{
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
glfwWaitEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
DestroyWindow(handle);
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user