Chris Robinson : wgl: Store the fbconfig id with the window when a pixel format is set.
Alexandre Julliard
julliard at winehq.org
Tue Sep 18 05:30:57 CDT 2007
Module: wine
Branch: master
Commit: d9571c9e6fa0b8f255815c5128c2859348ea70e6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d9571c9e6fa0b8f255815c5128c2859348ea70e6
Author: Chris Robinson <chris.kcat at gmail.com>
Date: Sat Sep 15 13:02:32 2007 -0700
wgl: Store the fbconfig id with the window when a pixel format is set.
---
dlls/opengl32/tests/opengl.c | 25 +++++++++++++++++++++++++
dlls/winex11.drv/dce.c | 7 +++++++
dlls/winex11.drv/event.c | 2 ++
dlls/winex11.drv/init.c | 1 +
dlls/winex11.drv/opengl.c | 35 +++++++++++++++++++++++++++++++++++
dlls/winex11.drv/window.c | 32 ++++++++++++++++++++++++++++++++
dlls/winex11.drv/x11drv.h | 9 ++++++++-
7 files changed, 110 insertions(+), 1 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c
index 268bece..2d08cfb 100644
--- a/dlls/opengl32/tests/opengl.c
+++ b/dlls/opengl32/tests/opengl.c
@@ -294,6 +294,29 @@ static void test_make_current_read(HDC hdc)
ok(hread == hdc, "wglGetCurrentReadDCARB failed for wglMakeContextCurrent\n");
}
+static void test_dc(HWND hwnd, HDC hdc)
+{
+ int pf1, pf2;
+ HDC hdc2;
+
+ /* Get another DC and make sure it has the same pixel format */
+ hdc2 = GetDC(hwnd);
+ if(hdc != hdc2)
+ {
+ pf1 = GetPixelFormat(hdc);
+ pf2 = GetPixelFormat(hdc2);
+ ok(pf1 == pf2, "Second DC does not have the same format (%d != %d)\n", pf1, pf2);
+ }
+ else
+ skip("Could not get a different DC for the window\n");
+
+ if(hdc2)
+ {
+ ReleaseDC(hwnd, hdc2);
+ hdc2 = NULL;
+ }
+}
+
START_TEST(opengl)
{
HWND hwnd;
@@ -336,6 +359,8 @@ START_TEST(opengl)
res = SetPixelFormat(hdc, iPixelFormat, &pfd);
ok(res, "SetPixelformat failed: %x\n", GetLastError());
+ test_dc(hwnd, hdc);
+
hglrc = wglCreateContext(hdc);
res = wglMakeCurrent(hdc, hglrc);
ok(res, "wglMakeCurrent failed!\n");
diff --git a/dlls/winex11.drv/dce.c b/dlls/winex11.drv/dce.c
index 72c5429..aa37a4a 100644
--- a/dlls/winex11.drv/dce.c
+++ b/dlls/winex11.drv/dce.c
@@ -148,9 +148,15 @@ static void update_visible_region( struct dce *dce )
if (top == dce->hwnd && ((data = X11DRV_get_win_data( dce->hwnd )) != NULL) &&
IsIconic( dce->hwnd ) && data->icon_window)
+ {
escape.drawable = data->icon_window;
+ escape.fbconfig_id = 0;
+ }
else
+ {
escape.drawable = X11DRV_get_whole_window( top );
+ escape.fbconfig_id = X11DRV_get_fbconfig_id( dce->hwnd );
+ }
escape.code = X11DRV_SET_DRAWABLE;
escape.mode = IncludeInferiors;
@@ -185,6 +191,7 @@ static void release_dce( struct dce *dce )
escape.drawable_rect = virtual_screen_rect;
SetRect( &escape.dc_rect, 0, 0, virtual_screen_rect.right - virtual_screen_rect.left,
virtual_screen_rect.bottom - virtual_screen_rect.top );
+ escape.fbconfig_id = 0;
ExtEscape( dce->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
}
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index f3010de..d06ade8 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -958,6 +958,8 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
return X11DRV_AcquireClipboard( hwnd );
case WM_X11DRV_DELETE_WINDOW:
return SendMessageW( hwnd, WM_SYSCOMMAND, SC_CLOSE, 0 );
+ case WM_X11DRV_SET_WIN_FORMAT:
+ return X11DRV_set_win_format( hwnd, (XID)wp );
default:
FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
return 0;
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c
index 4bb44f2..0946257 100644
--- a/dlls/winex11.drv/init.c
+++ b/dlls/winex11.drv/init.c
@@ -340,6 +340,7 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID
physDev->dc_rect = data->dc_rect;
physDev->drawable = data->drawable;
physDev->drawable_rect = data->drawable_rect;
+ physDev->current_pf = pixelformat_from_fbconfig_id( data->fbconfig_id );
wine_tsx11_lock();
XSetSubwindowMode( gdi_display, physDev->gc, data->mode );
wine_tsx11_unlock();
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 156a574..fc33143 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -935,6 +935,20 @@ static WineGLPixelFormat* ConvertPixelFormatGLXtoWGL(Display *display, int fmt_i
return NULL;
}
+int pixelformat_from_fbconfig_id(XID fbconfig_id)
+{
+ WineGLPixelFormat *fmt;
+
+ if (!fbconfig_id) return 0;
+
+ fmt = ConvertPixelFormatGLXtoWGL(gdi_display, fbconfig_id);
+ if(fmt)
+ return fmt->iPixelFormat;
+ /* This will happen on hwnds without a pixel format set; it's ok */
+ return 0;
+}
+
+
/**
* X11DRV_ChoosePixelFormat
*
@@ -1349,6 +1363,7 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
const PIXELFORMATDESCRIPTOR *ppfd) {
WineGLPixelFormat *fmt;
int value;
+ HWND hwnd;
TRACE("(%p,%d,%p)\n", physDev, iPixelFormat, ppfd);
@@ -1371,6 +1386,21 @@ BOOL X11DRV_SetPixelFormat(X11DRV_PDEVICE *physDev,
return 0;
}
+ pglXGetFBConfigAttrib(gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &value);
+
+ hwnd = WindowFromDC(physDev->hdc);
+ if(hwnd) {
+ if(!(value&GLX_WINDOW_BIT)) {
+ WARN("Pixel format %d is not compatible for window rendering\n", iPixelFormat);
+ return 0;
+ }
+
+ if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, (WPARAM)fmt->fmt_id, 0)) {
+ ERR("Couldn't set format of the window, returning failure\n");
+ return 0;
+ }
+ }
+
physDev->current_pf = iPixelFormat;
if (TRACE_ON(opengl)) {
@@ -3345,6 +3375,11 @@ XVisualInfo *X11DRV_setup_opengl_visual( Display *display )
#else /* no OpenGL includes */
+int pixelformat_from_fbconfig_id(XID fbconfig_id)
+{
+ return 0;
+}
+
/***********************************************************************
* ChoosePixelFormat (X11DRV.@)
*/
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index e55fcfd..b0a7460 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -55,6 +55,7 @@ static XContext win_data_context;
static const char whole_window_prop[] = "__wine_x11_whole_window";
static const char icon_window_prop[] = "__wine_x11_icon_window";
+static const char fbconfig_id_prop[] = "__wine_x11_fbconfig_id";
static const char managed_prop[] = "__wine_x11_managed";
static const char visual_id_prop[] = "__wine_x11_visual_id";
@@ -166,6 +167,21 @@ void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data )
/***********************************************************************
+ * X11DRV_set_win_format
+ */
+BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig_id )
+{
+ struct x11drv_win_data *data;
+
+ if (!(data = X11DRV_get_win_data(hwnd))) return FALSE;
+
+ data->fbconfig_id = fbconfig_id;
+ SetPropA(hwnd, fbconfig_id_prop, (HANDLE)data->fbconfig_id);
+ return TRUE;
+}
+
+
+/***********************************************************************
* get_window_changes
*
* fill the window changes structure
@@ -937,6 +953,7 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
data->hwnd = hwnd;
data->whole_window = 0;
data->icon_window = 0;
+ data->fbconfig_id = 0;
data->xic = 0;
data->managed = FALSE;
data->dce = NULL;
@@ -1229,6 +1246,21 @@ Window X11DRV_get_whole_window( HWND hwnd )
/***********************************************************************
+ * X11DRV_get_fbconfig_id
+ *
+ * Return the GLXFBConfig ID of the drawable used by the window for
+ * OpenGL rendering. This is 0 for windows without a pixel format set.
+ */
+XID X11DRV_get_fbconfig_id( HWND hwnd )
+{
+ struct x11drv_win_data *data = X11DRV_get_win_data( hwnd );
+
+ if (!data) return (XID)GetPropA( hwnd, fbconfig_id_prop );
+ return data->fbconfig_id;
+}
+
+
+/***********************************************************************
* X11DRV_get_ic
*
* Return the X input context associated with a window
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 1583411..f61dc98 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -485,6 +485,7 @@ struct x11drv_escape_set_drawable
int mode; /* ClipByChildren or IncludeInferiors */
RECT dc_rect; /* DC rectangle relative to drawable */
RECT drawable_rect;/* Drawable rectangle relative to screen */
+ XID fbconfig_id; /* fbconfig id used by the GL drawable */
};
struct x11drv_escape_set_dce
@@ -633,7 +634,8 @@ extern DWORD EVENT_x11_time_to_win32_time(Time time);
enum x11drv_window_messages
{
WM_X11DRV_ACQUIRE_SELECTION = 0x80001000,
- WM_X11DRV_DELETE_WINDOW
+ WM_X11DRV_DELETE_WINDOW,
+ WM_X11DRV_SET_WIN_FORMAT
};
/* x11drv private window data */
@@ -642,6 +644,7 @@ struct x11drv_win_data
HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */
Window icon_window; /* X window for the icon */
+ XID fbconfig_id; /* fbconfig id for the GL drawable this hwnd uses */
RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* X window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to whole window */
@@ -656,8 +659,12 @@ struct x11drv_win_data
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd );
+extern XID X11DRV_get_fbconfig_id( HWND hwnd );
extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
extern XIC X11DRV_get_ic( HWND hwnd );
+extern BOOL X11DRV_set_win_format( HWND hwnd, XID fbconfig );
+
+extern int pixelformat_from_fbconfig_id( XID fbconfig_id );
extern void alloc_window_dce( struct x11drv_win_data *data );
extern void free_window_dce( struct x11drv_win_data *data );
More information about the wine-cvs
mailing list