summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosé Fonseca <[email protected]>2009-04-09 20:35:55 +0100
committerJosé Fonseca <[email protected]>2009-04-09 20:45:43 +0100
commit4bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9d (patch)
treeece258e53a0daa48aff2c871510b01370135056b
parentdeff09921563419a77bd1aad0054afa34214ed1a (diff)
wgl: Use hooks instead of subclassing the window.
Subclassing the window is invasive: we might call an old window proc even after it was removed. Glut and another bug just in the wrong time was provoking this. Hooks don't have this problem.
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_device.c8
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_framebuffer.c95
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_framebuffer.h7
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_tls.h3
4 files changed, 83 insertions, 30 deletions
diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/shared/stw_device.c
index c6d59afa033..8e0193d7bef 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_device.c
@@ -41,6 +41,7 @@
#include "shared/stw_pixelformat.h"
#include "shared/stw_public.h"
#include "shared/stw_tls.h"
+#include "shared/stw_framebuffer.h"
#ifdef WIN32_THREADS
extern _glthread_Mutex OneTimeLock;
@@ -132,9 +133,11 @@ error1:
boolean
st_init_thread(void)
{
- if (!stw_tls_init_thread()) {
+ if (!stw_tls_init_thread())
+ return FALSE;
+
+ if (!stw_framebuffer_init_thread())
return FALSE;
- }
return TRUE;
}
@@ -143,6 +146,7 @@ st_init_thread(void)
void
st_cleanup_thread(void)
{
+ stw_framebuffer_cleanup_thread();
stw_tls_cleanup_thread();
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
index d6cf6fb5347..053f741e7b6 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
@@ -42,6 +42,7 @@
#include "stw_device.h"
#include "stw_public.h"
#include "stw_winsys.h"
+#include "stw_tls.h"
void
@@ -53,26 +54,43 @@ stw_framebuffer_resize(
st_resize_framebuffer( fb->stfb, width, height );
}
+/**
+ * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
+ * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
+ */
static LRESULT CALLBACK
-stw_window_proc(
- HWND hWnd,
- UINT uMsg,
+stw_call_window_proc(
+ int nCode,
WPARAM wParam,
LPARAM lParam )
{
- struct stw_framebuffer *fb;
-
- pipe_mutex_lock( stw_dev->mutex );
- for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
- if (fb->hWnd == hWnd)
- break;
- pipe_mutex_unlock( stw_dev->mutex );
- assert( fb != NULL );
-
- if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED)
- stw_framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) );
+ struct stw_tls_data *tls_data;
+ PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return 0;
+
+ if (nCode < 0)
+ return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
+
+ if (pParams->message == WM_SIZE && pParams->wParam != SIZE_MINIMIZED) {
+ struct stw_framebuffer *fb;
+
+ pipe_mutex_lock( stw_dev->mutex );
+ for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
+ if (fb->hWnd == pParams->hwnd)
+ break;
+ pipe_mutex_unlock( stw_dev->mutex );
+
+ if(fb) {
+ unsigned width = LOWORD( pParams->lParam );
+ unsigned height = HIWORD( pParams->lParam );
+ stw_framebuffer_resize( fb, width, height );
+ }
+ }
- return CallWindowProc( fb->WndProc, hWnd, uMsg, wParam, lParam );
+ return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
}
static INLINE boolean
@@ -190,16 +208,7 @@ stw_framebuffer_create(
fb->cColorBits = GetDeviceCaps( hdc, BITSPIXEL );
fb->hDC = hdc;
-
- /* Subclass a window associated with the device context.
- */
fb->hWnd = WindowFromDC( hdc );
- if (fb->hWnd != NULL) {
- fb->WndProc = (WNDPROC) SetWindowLongPtr(
- fb->hWnd,
- GWLP_WNDPROC,
- (LONG_PTR) stw_window_proc );
- }
pipe_mutex_lock( stw_dev->mutex );
fb->next = stw_dev->fb_head;
@@ -227,9 +236,6 @@ stw_framebuffer_destroy(
pipe_mutex_unlock( stw_dev->mutex );
- if (fb->hWnd)
- SetWindowLongPtr( fb->hWnd, GWLP_WNDPROC, (LONG_PTR)fb->WndProc );
-
FREE( fb );
}
@@ -286,3 +292,38 @@ stw_swap_buffers(
return TRUE;
}
+
+
+boolean
+stw_framebuffer_init_thread(void)
+{
+ struct stw_tls_data *tls_data;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return FALSE;
+
+ tls_data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
+ stw_call_window_proc,
+ NULL,
+ GetCurrentThreadId());
+ if(tls_data->hCallWndProcHook == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+stw_framebuffer_cleanup_thread(void)
+{
+ struct stw_tls_data *tls_data;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return;
+
+ if(tls_data->hCallWndProcHook) {
+ UnhookWindowsHookEx(tls_data->hCallWndProcHook);
+ tls_data->hCallWndProcHook = NULL;
+ }
+}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
index c2822f6d6de..245fdc5fc9e 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
@@ -39,7 +39,6 @@ struct stw_framebuffer
HDC hDC;
BYTE cColorBits;
HWND hWnd;
- WNDPROC WndProc;
struct stw_framebuffer *next;
};
@@ -64,4 +63,10 @@ struct stw_framebuffer *
stw_framebuffer_from_hdc(
HDC hdc );
+boolean
+stw_framebuffer_init_thread(void);
+
+void
+stw_framebuffer_cleanup_thread(void);
+
#endif /* STW_FRAMEBUFFER_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.h b/src/gallium/state_trackers/wgl/shared/stw_tls.h
index 23b61e68ff5..f5a6bdf4b1a 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_tls.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_tls.h
@@ -28,11 +28,14 @@
#ifndef STW_TLS_H
#define STW_TLS_H
+#include <windows.h>
+
struct stw_tls_data
{
uint currentPixelFormat;
HDC currentDC;
UINT_PTR currentGLRC;
+ HHOOK hCallWndProcHook;
};
boolean