summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-26 20:30:52 +0200
committerwm4 <wm4@nowhere>2014-07-26 20:30:52 +0200
commit3f268cc4f2a498f909f9199b1683d2c6eb285af8 (patch)
treef4939c9a080932759f0e5e760382cd1e1e7f1cea
parent559fe1daace8f48a8dc37906f840e9981b961415 (diff)
downloadmpv-3f268cc4f2a498f909f9199b1683d2c6eb285af8.tar.bz2
mpv-3f268cc4f2a498f909f9199b1683d2c6eb285af8.tar.xz
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.)
-rw-r--r--video/out/w32_common.c19
1 files changed, 9 insertions, 10 deletions
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;
}