summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2009-04-09 20:35:55 +0100
committerJosé Fonseca <jfonseca@vmware.com>2009-04-09 20:45:43 +0100
commit4bbb5eb96ad9f2e5b6e064854eeb5f5cb1498f9d (patch)
treeece258e53a0daa48aff2c871510b01370135056b /src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
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.
Diffstat (limited to 'src/gallium/state_trackers/wgl/shared/stw_framebuffer.c')
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_framebuffer.c95
1 files changed, 68 insertions, 27 deletions
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
index d6cf6fb534..053f741e7b 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;
+ }
+}