summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossymiles@gmail.com>2017-05-16 00:27:26 +1000
committerJames Ross-Gowan <rossymiles@gmail.com>2017-05-16 20:13:09 +1000
commitfe09d7614263fe6e1599312dfc14f3aff8218218 (patch)
treeadfef1f5ba8f7b70650afde09e353c005a10cb61
parent6fe75c38d87650dcc7f8acbd951842f5a8a101ac (diff)
downloadmpv-fe09d7614263fe6e1599312dfc14f3aff8218218.tar.bz2
mpv-fe09d7614263fe6e1599312dfc14f3aff8218218.tar.xz
w32_common: drop TLS usage
This was added in 3f268cc4f2a4 because it wasn't clear whether WM_NCCREATE could be used to send a context pointer from CreateWindowEx to the window procedure. WM_NCCREATE isn't always the first message sent to a window, but this seems to be because of an undocumented but well-known bug where, for top-level overlapped windows, a spurious WM_GETMINMAXINFO arrives first instead. The WM_GETMINMAXINFO can be safely ignored, so it is still okay to pass the context struct in WM_NCCREATE.
-rw-r--r--video/out/w32_common.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index ce9ff771b7..42d0135f74 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -62,8 +62,6 @@ typedef enum MONITOR_DPI_TYPE {
} MONITOR_DPI_TYPE;
#endif
-static __thread struct vo_w32_state *w32_thread_context;
-
struct w32_api {
HRESULT (WINAPI *pGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
};
@@ -874,11 +872,21 @@ static void reinit_window_state(struct vo_w32_state *w32)
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
- assert(w32_thread_context);
- struct vo_w32_state *w32 = w32_thread_context;
- if (!w32->window)
- w32->window = hWnd; // can happen during CreateWindow*!
- assert(w32->window == hWnd);
+ struct vo_w32_state *w32 = (void*)GetWindowLongPtrW(hWnd, GWLP_USERDATA);
+ if (!w32) {
+ // WM_NCCREATE is supposed to be the first message that a window
+ // receives. It allows struct vo_w32_state to be passed from
+ // CreateWindow's lpParam to the window procedure. However, as a
+ // longstanding Windows bug, overlapped top-level windows will get a
+ // WM_GETMINMAXINFO before WM_NCCREATE. This can be ignored.
+ if (message != WM_NCCREATE)
+ return DefWindowProcW(hWnd, message, wParam, lParam);
+
+ CREATESTRUCTW *cs = (CREATESTRUCTW *)lParam;
+ w32 = cs->lpCreateParams;
+ w32->window = hWnd;
+ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)w32);
+ }
switch (message) {
case WM_USER:
@@ -1321,8 +1329,6 @@ static void *gui_thread(void *ptr)
w32_api_load(w32);
thread_disable_ime();
- w32_thread_context = w32;
-
if (w32->opts->WinID >= 0)
w32->parent = (HWND)(intptr_t)(w32->opts->WinID);
@@ -1330,20 +1336,17 @@ static void *gui_thread(void *ptr)
if (w32->parent) {
RECT r;
GetClientRect(w32->parent, &r);
- w32->window = CreateWindowExW(WS_EX_NOPARENTNOTIFY,
- (LPWSTR)MAKEINTATOM(cls), L"mpv",
- WS_CHILD | WS_VISIBLE,
- 0, 0, r.right, r.bottom,
- w32->parent, 0, HINST_THISCOMPONENT, NULL);
+ CreateWindowExW(WS_EX_NOPARENTNOTIFY, (LPWSTR)MAKEINTATOM(cls), L"mpv",
+ WS_CHILD | WS_VISIBLE, 0, 0, r.right, r.bottom,
+ w32->parent, 0, HINST_THISCOMPONENT, w32);
// Install a hook to get notifications when the parent changes size
if (w32->window)
install_parent_hook(w32);
} else {
- w32->window = CreateWindowExW(0, (LPWSTR)MAKEINTATOM(cls), L"mpv",
- update_style(w32, 0),
- CW_USEDEFAULT, SW_HIDE, 100, 100,
- 0, 0, HINST_THISCOMPONENT, NULL);
+ CreateWindowExW(0, (LPWSTR)MAKEINTATOM(cls), L"mpv",
+ update_style(w32, 0), CW_USEDEFAULT, SW_HIDE, 100, 100,
+ 0, 0, HINST_THISCOMPONENT, w32);
}
if (!w32->window) {
@@ -1423,8 +1426,6 @@ done:
if (ole_ok)
OleUninitialize();
SetThreadExecutionState(ES_CONTINUOUS);
-
- w32_thread_context = NULL;
return NULL;
}