From 64e2ee2ca81cf7d772bad2f471073e1066572c17 Mon Sep 17 00:00:00 2001 From: Yaron Cohen-Tal Date: Sun, 30 Aug 2015 15:32:07 +0300 Subject: [PATCH] Fix a bug in which "DllMain" isn't called when using the static version of Epoxy in Windows. --- src/CMakeLists.txt | 27 +++++++---- src/dispatch_common.h | 6 ++- src/dispatch_wgl.c | 58 ++---------------------- src/dllmain.c | 101 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+), 64 deletions(-) mode change 100644 => 100755 src/dispatch_common.h create mode 100644 src/dllmain.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aac7ba9..631f102 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,21 +63,28 @@ if (EPOXY_SUPPORT_WGL) "${CMAKE_CURRENT_BINARY_DIR}/../include/epoxy/wgl_generated.h") endif () +set (EPOXY_INCLUDE_DIRS "../include" + "${CMAKE_CURRENT_BINARY_DIR}/../include" + "${CMAKE_CURRENT_SOURCE_DIR}") + set (TARGET_OBJS_NAME "${TARGET_NAME}_objs") add_library ("${TARGET_NAME}_objs" OBJECT ${SOURCES} ${HEADERS}) set_target_properties ("${TARGET_NAME}_objs" PROPERTIES POSITION_INDEPENDENT_CODE TRUE) -target_include_directories ("${TARGET_NAME}_objs" PUBLIC - "../include" - "${CMAKE_CURRENT_BINARY_DIR}/../include" - "${CMAKE_CURRENT_SOURCE_DIR}") +target_include_directories ("${TARGET_NAME}_objs" PUBLIC ${EPOXY_INCLUDE_DIRS}) if (CMAKE_C_COMPILER_ID STREQUAL "MSVC") target_compile_definitions ("${TARGET_NAME}_objs" PUBLIC "inline=__inline" EPOXY_EXPORTS) endif () +set (EPOXY_LIBS_FILES $) +if (WIN32) + set (EPOXY_LIBS_EXTRA_FILES dllmain.c) +else () + set (EPOXY_LIBS_EXTRA_FILES "") +endif () set (TARGETS_BUILT_NAMES "") if (EPOXY_BUILD_SHARED) list (APPEND TARGETS_BUILT_NAMES "${TARGET_NAME}_shared") - add_library ("${TARGET_NAME}_shared" SHARED $) + add_library ("${TARGET_NAME}_shared" SHARED $ ${EPOXY_LIBS_EXTRA_FILES}) if (WIN32 OR ANDROID) set_target_properties ("${TARGET_NAME}_shared" PROPERTIES OUTPUT_NAME "${TARGET_OUTPUT_NAME}_${TARGET_ABI_VER}") @@ -90,10 +97,12 @@ if (EPOXY_BUILD_SHARED) VERSION "${TARGET_VER}" SOVERSION "${TARGET_ABI_VER}") endif () -endif() + target_include_directories ("${TARGET_NAME}_shared" PUBLIC ${EPOXY_INCLUDE_DIRS}) + target_compile_definitions ("${TARGET_NAME}_shared" PUBLIC EPOXY_EXPORTS EPOXY_BUILDING_SHARED_LIB) +endif () if (EPOXY_BUILD_STATIC) list (APPEND TARGETS_BUILT_NAMES "${TARGET_NAME}_static") - add_library ("${TARGET_NAME}_static" STATIC $) + add_library ("${TARGET_NAME}_static" STATIC $ ${EPOXY_LIBS_EXTRA_FILES}) if (WIN32) set_target_properties ("${TARGET_NAME}_static" PROPERTIES OUTPUT_NAME "${TARGET_OUTPUT_NAME}_static_${TARGET_ABI_VER}") @@ -101,7 +110,9 @@ if (EPOXY_BUILD_STATIC) set_target_properties ("${TARGET_NAME}_static" PROPERTIES OUTPUT_NAME "${TARGET_OUTPUT_NAME}_${TARGET_ABI_VER}") endif () -endif() + target_include_directories ("${TARGET_NAME}_static" PUBLIC ${EPOXY_INCLUDE_DIRS}) + target_compile_definitions ("${TARGET_NAME}_static" PUBLIC EPOXY_EXPORTS EPOXY_BUILDING_STATIC_LIB) +endif () install (FILES ${HEADERS} DESTINATION "include/epoxy") install (TARGETS ${TARGETS_BUILT_NAMES} RUNTIME DESTINATION bin diff --git a/src/dispatch_common.h b/src/dispatch_common.h old mode 100644 new mode 100755 index 262f34d..4e4414f --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -166,4 +166,8 @@ extern BOOL UNWRAPPED_PROTO(wglMakeCurrent_unwrapped)(HDC hdc, HGLRC hglrc); extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentARB_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); extern BOOL UNWRAPPED_PROTO(wglMakeContextCurrentEXT_unwrapped)(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); extern BOOL UNWRAPPED_PROTO(wglMakeAssociatedContextCurrentAMD_unwrapped)(HGLRC hglrc); -#endif /* _WIN32_ */ +#endif /* _WIN32 */ + +#if EPOXY_SUPPORT_WGL +extern bool epoxy_first_context_current; +#endif diff --git a/src/dispatch_wgl.c b/src/dispatch_wgl.c index 64257a1..3ce4406 100644 --- a/src/dispatch_wgl.c +++ b/src/dispatch_wgl.c @@ -27,7 +27,7 @@ #include "dispatch_common.h" -static bool first_context_current = false; +bool epoxy_first_context_current = false; static bool already_switched_to_dispatch_table = false; /** @@ -75,8 +75,8 @@ epoxy_has_wgl_extension(HDC hdc, const char *ext) EPOXY_IMPORTEXPORT void epoxy_handle_external_wglMakeCurrent(void) { - if (!first_context_current) { - first_context_current = true; + if (!epoxy_first_context_current) { + epoxy_first_context_current = true; } else { if (!already_switched_to_dispatch_table) { already_switched_to_dispatch_table = true; @@ -89,58 +89,6 @@ epoxy_handle_external_wglMakeCurrent(void) } } -/** - * This global symbol is apparently looked up by Windows when loading - * a DLL, but it doesn't declare the prototype. - */ -BOOL WINAPI -DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved); - -BOOL WINAPI -DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) -{ - void *data; - - switch (reason) { - case DLL_PROCESS_ATTACH: - gl_tls_index = TlsAlloc(); - if (gl_tls_index == TLS_OUT_OF_INDEXES) - return FALSE; - wgl_tls_index = TlsAlloc(); - if (wgl_tls_index == TLS_OUT_OF_INDEXES) - return FALSE; - - first_context_current = false; - - /* FALLTHROUGH */ - - case DLL_THREAD_ATTACH: - data = LocalAlloc(LPTR, gl_tls_size); - TlsSetValue(gl_tls_index, data); - - data = LocalAlloc(LPTR, wgl_tls_size); - TlsSetValue(wgl_tls_index, data); - - break; - - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - data = TlsGetValue(gl_tls_index); - LocalFree(data); - - data = TlsGetValue(wgl_tls_index); - LocalFree(data); - - if (reason == DLL_PROCESS_DETACH) { - TlsFree(gl_tls_index); - TlsFree(wgl_tls_index); - } - break; - } - - return TRUE; -} - WRAPPER_VISIBILITY (BOOL) WRAPPER(epoxy_wglMakeCurrent)(HDC hdc, HGLRC hglrc) { diff --git a/src/dllmain.c b/src/dllmain.c new file mode 100644 index 0000000..861665f --- /dev/null +++ b/src/dllmain.c @@ -0,0 +1,101 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if !defined _WIN32 +#error This file should only be used in Windows. +#endif + +#include "dispatch_common.h" + +/** + * This global symbol is apparently looked up by Windows when loading + * a DLL, but it doesn't declare the prototype. + */ +BOOL WINAPI +DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved); + +BOOL WINAPI +DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) +{ + void *data; + + switch (reason) { + case DLL_PROCESS_ATTACH: + gl_tls_index = TlsAlloc(); + if (gl_tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + wgl_tls_index = TlsAlloc(); + if (wgl_tls_index == TLS_OUT_OF_INDEXES) + return FALSE; + + epoxy_first_context_current = false; + + /* FALLTHROUGH */ + + case DLL_THREAD_ATTACH: + data = LocalAlloc(LPTR, gl_tls_size); + TlsSetValue(gl_tls_index, data); + + data = LocalAlloc(LPTR, wgl_tls_size); + TlsSetValue(wgl_tls_index, data); + + break; + + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + data = TlsGetValue(gl_tls_index); + LocalFree(data); + + data = TlsGetValue(wgl_tls_index); + LocalFree(data); + + if (reason == DLL_PROCESS_DETACH) { + TlsFree(gl_tls_index); + TlsFree(wgl_tls_index); + } + break; + } + + return TRUE; +} + +#ifdef EPOXY_BUILDING_STATIC_LIB +#ifdef __GNUC__ + PIMAGE_TLS_CALLBACK dllmain_callback __attribute__((section(".CRT$XLB"))) = (PIMAGE_TLS_CALLBACK)DllMain; +#else +# ifdef _WIN64 +# pragma comment(linker, "/INCLUDE:_tls_used") +# pragma comment(linker, "/INCLUDE:dllmain_callback") +# pragma const_seg(".CRT$XLB") + extern const PIMAGE_TLS_CALLBACK dllmain_callback; + const PIMAGE_TLS_CALLBACK dllmain_callback = DllMain; +# pragma const_seg() +# else +# pragma comment(linker, "/INCLUDE:__tls_used") +# pragma comment(linker, "/INCLUDE:_dllmain_callback") +# pragma data_seg(".CRT$XLB") + PIMAGE_TLS_CALLBACK dllmain_callback = DllMain; +# pragma data_seg() +# endif +#endif +#endif