From fe09d7614263fe6e1599312dfc14f3aff8218218 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Tue, 16 May 2017 00:27:26 +1000 Subject: 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. --- video/out/w32_common.c | 41 +++++++++++++++++++++-------------------- 1 file 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; } -- cgit v1.2.3