From 3f268cc4f2a498f909f9199b1683d2c6eb285af8 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 26 Jul 2014 20:30:52 +0200 Subject: win32: use gcc TLS instead of WM_NCCREATE tricks for window context win32 does not provide a proper per-window context pointer. Although it does allow passing a user-chosen value to WM_CREATE/WM_NCCREATE, this is not enough - the first message doesn't even have to be WM_NCCREATE. This gets us in trouble later on, so go the easy route and just use a TLS variable. __thread is gcc specific, but Windows is a very "special" platform anyway. We support only MinGW and Cygwin on it, so who cares. (C11 standardizes __thread as _Thread_local; we can use that later.) --- video/out/w32_common.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'video') diff --git a/video/out/w32_common.c b/video/out/w32_common.c index cfbdfcd65d..8b3fccb714 100644 --- a/video/out/w32_common.c +++ b/video/out/w32_common.c @@ -40,6 +40,8 @@ static const wchar_t classname[] = L"mpv"; +static __thread struct vo_w32_state *w32_thread_context; + struct vo_w32_state { struct mp_log *log; struct vo *vo; @@ -492,14 +494,8 @@ static bool handle_char(struct vo_w32_state *w32, wchar_t wc) static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (message == WM_NCCREATE) { - CREATESTRUCT *cs = (void*)lParam; - SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)cs->lpCreateParams); - } - struct vo_w32_state *w32 = (void*)GetWindowLongPtrW(hWnd, GWLP_USERDATA); - // message before WM_NCCREATE, pray to Raymond Chen that it's not important - if (!w32) - return DefWindowProcW(hWnd, message, wParam, lParam); + assert(w32_thread_context); + struct vo_w32_state *w32 = w32_thread_context; int mouse_button = 0; switch (message) { @@ -937,6 +933,8 @@ int vo_w32_init(struct vo *vo) return 0; } + w32_thread_context = w32; + if (w32->opts->WinID >= 0) { RECT r; GetClientRect(WIN_ID_TO_HWND(w32->opts->WinID), &r); @@ -945,13 +943,13 @@ int vo_w32_init(struct vo *vo) WS_CHILD | WS_VISIBLE, 0, 0, r.right, r.bottom, WIN_ID_TO_HWND(w32->opts->WinID), - 0, hInstance, w32); + 0, hInstance, NULL); } else { w32->window = CreateWindowExW(0, classname, classname, update_style(w32, 0), CW_USEDEFAULT, SW_HIDE, 100, 100, - 0, 0, hInstance, w32); + 0, 0, hInstance, NULL); } if (!w32->window) { @@ -1081,6 +1079,7 @@ void vo_w32_uninit(struct vo *vo) SetThreadExecutionState(ES_CONTINUOUS); DestroyWindow(w32->window); UnregisterClassW(classname, 0); + w32_thread_context = NULL; talloc_free(w32); vo->w32 = NULL; } -- cgit v1.2.3