diff options
4 files changed, 81 insertions, 28 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; +   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); -   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 (pParams->message == WM_SIZE && pParams->wParam != SIZE_MINIMIZED) { +      struct stw_framebuffer *fb; -   if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED) -      stw_framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) ); +      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 | 
