summaryrefslogtreecommitdiff
path: root/src/gallium/state_trackers/wgl/shared
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
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')
-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 c6d59afa03..8e0193d7be 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 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;
+ }
+}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
index c2822f6d6d..245fdc5fc9 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 23b61e68ff..f5a6bdf4b1 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