From: Alexandros Frantzis alexandros.frantzis@collabora.com
Introduce a new wgl driver callback function to allow the driver to provide a complete list of all pixel formats and their attributes. If the driver provides the information use it to implement wglDescribePixelFormat. --- dlls/opengl32/make_opengl | 24 ++++++++++++++++++- dlls/opengl32/thunks.c | 9 ------- dlls/opengl32/unix_thunks.c | 4 ++++ dlls/opengl32/unix_wgl.c | 35 +++++++++++++++++++++++++++ dlls/opengl32/unixlib.h | 11 +++++++++ dlls/opengl32/wgl.c | 47 +++++++++++++++++++++++++++++++++++++ include/wine/wgl_driver.h | 8 ++++++- 7 files changed, 127 insertions(+), 11 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index ec6c7cbe4df..215caad4639 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -176,6 +176,7 @@ my %manual_win_thunks = "glUnmapBufferARB" => 1, "glUnmapNamedBuffer" => 1, "glUnmapNamedBufferEXT" => 1, + "wglDescribePixelFormat" => 1, "wglGetCurrentReadDCARB" => 1, "wglGetExtensionsStringARB" => 1, "wglGetExtensionsStringEXT" => 1, @@ -880,6 +881,11 @@ printf HEADER "#define WINE_WGL_DRIVER_VERSION %u\n\n", $wgl_version + 1; print HEADER "struct wgl_context;\n"; print HEADER "struct wgl_pbuffer;\n\n";
+print HEADER "struct wgl_pixel_format\n"; +print HEADER "{\n"; +print HEADER " PIXELFORMATDESCRIPTOR pfd;\n"; +print HEADER "};\n\n"; + print HEADER "struct opengl_funcs\n{\n"; print HEADER " struct\n {\n"; foreach (sort keys %wgl_functions) @@ -889,6 +895,7 @@ foreach (sort keys %wgl_functions) my $func_ret = get_func_ret( $wgl_functions{$_}, 1 ); printf HEADER " %-10s (WINE_GLAPI *p_$_)($decl_args);\n", $func_ret; } +printf HEADER " %-10s (WINE_GLAPI *p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats );\n", "void"; print HEADER " } wgl;\n\n";
print HEADER " struct\n {\n"; @@ -1012,10 +1019,21 @@ foreach (sort keys %ext_functions) print OUT generate_func_params($_, $ext_functions{$_}); }
+print OUT "struct get_pixel_formats_params\n"; +print OUT "{\n"; +print OUT " TEB *teb;\n"; +print OUT " HDC hdc;\n"; +print OUT " struct wgl_pixel_format *formats;\n"; +print OUT " unsigned int max_formats;\n"; +print OUT " unsigned int num_formats;\n"; +print OUT " unsigned int num_onscreen_formats;\n"; +print OUT "};\n\n"; + print OUT "enum unix_funcs\n"; print OUT "{\n"; print OUT " unix_thread_attach,\n"; print OUT " unix_process_detach,\n"; +print OUT " unix_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1139,6 +1157,7 @@ print OUT "#endif\n\n";
print OUT "extern NTSTATUS thread_attach( void *args );\n"; print OUT "extern NTSTATUS process_detach( void *args );\n"; +print OUT "extern NTSTATUS get_pixel_formats( void *args );\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1185,6 +1204,7 @@ print OUT "const unixlib_entry_t __wine_unix_call_funcs[] =\n"; print OUT "{\n"; print OUT " &thread_attach,\n"; print OUT " &process_detach,\n"; +print OUT " &get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1206,7 +1226,8 @@ print OUT "\n"; print OUT "#ifdef _WIN64\n\n"; print OUT "typedef ULONG PTR32;\n\n"; print OUT "extern NTSTATUS wow64_thread_attach( void *args );\n"; -print OUT "extern NTSTATUS wow64_process_detach( void *args );\n\n"; +print OUT "extern NTSTATUS wow64_process_detach( void *args );\n"; +print OUT "extern NTSTATUS wow64_get_pixel_formats( void *args );\n\n";
foreach (sort keys %wgl_functions) { @@ -1250,6 +1271,7 @@ print OUT "\nconst unixlib_entry_t __wine_unix_call_wow64_funcs[] =\n"; print OUT "{\n"; print OUT " wow64_thread_attach,\n"; print OUT " wow64_process_detach,\n"; +print OUT " wow64_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index c20abdf5488..49f32461de5 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -43,15 +43,6 @@ BOOL WINAPI wglDeleteContext( HGLRC oldContext ) return args.ret; }
-int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ) -{ - struct wglDescribePixelFormat_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .ipfd = ipfd, .cjpfd = cjpfd, .ppfd = ppfd }; - NTSTATUS status; - TRACE( "hdc %p, ipfd %d, cjpfd %u, ppfd %p\n", hdc, ipfd, cjpfd, ppfd ); - if ((status = UNIX_CALL( wglDescribePixelFormat, &args ))) WARN( "wglDescribePixelFormat returned %#lx\n", status ); - return args.ret; -} - BOOL WINAPI wglMakeCurrent( HDC hDc, HGLRC newContext ) { struct wglMakeCurrent_params args = { .teb = NtCurrentTeb(), .hDc = hDc, .newContext = newContext }; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index a2889e7cd32..abb436bdc05 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -24,6 +24,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(opengl);
extern NTSTATUS thread_attach( void *args ); extern NTSTATUS process_detach( void *args ); +extern NTSTATUS get_pixel_formats( void *args ); extern NTSTATUS wgl_wglCopyContext( void *args ); extern NTSTATUS wgl_wglCreateContext( void *args ); extern NTSTATUS wgl_wglDeleteContext( void *args ); @@ -24206,6 +24207,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { &thread_attach, &process_detach, + &get_pixel_formats, &wgl_wglCopyContext, &wgl_wglCreateContext, &wgl_wglDeleteContext, @@ -27254,6 +27256,7 @@ typedef ULONG PTR32;
extern NTSTATUS wow64_thread_attach( void *args ); extern NTSTATUS wow64_process_detach( void *args ); +extern NTSTATUS wow64_get_pixel_formats( void *args );
static NTSTATUS wow64_wgl_wglCopyContext( void *args ) { @@ -92326,6 +92329,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { wow64_thread_attach, wow64_process_detach, + wow64_get_pixel_formats, wow64_wgl_wglCopyContext, wow64_wgl_wglCreateContext, wow64_wgl_wglDeleteContext, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index b75a940d1d6..093dab4efb8 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1157,6 +1157,16 @@ NTSTATUS process_detach( void *args ) return STATUS_SUCCESS; }
+NTSTATUS get_pixel_formats( void *args ) +{ + struct get_pixel_formats_params *params = args; + const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); + if (!funcs || !funcs->wgl.p_get_pixel_formats) return STATUS_NOT_IMPLEMENTED; + funcs->wgl.p_get_pixel_formats( params->formats, params->max_formats, + ¶ms->num_formats, ¶ms->num_onscreen_formats ); + return STATUS_SUCCESS; +} + #ifdef _WIN64
typedef ULONG PTR32; @@ -2239,4 +2249,29 @@ NTSTATUS wow64_process_detach( void *args ) return STATUS_SUCCESS; }
+NTSTATUS wow64_get_pixel_formats( void *args ) +{ + struct + { + PTR32 teb; + PTR32 hdc; + PTR32 formats; + UINT max_formats; + UINT num_formats; + UINT num_onscreen_formats; + } *params32 = args; + struct get_pixel_formats_params params = + { + .teb = get_teb64(params32->teb), + .hdc = ULongToPtr(params32->hdc), + .formats = ULongToPtr(params32->formats), + .max_formats = params32->max_formats, + }; + NTSTATUS status; + status = get_pixel_formats( ¶ms ); + params32->num_formats = params.num_formats; + params32->num_onscreen_formats = params.num_onscreen_formats; + return status; +} + #endif diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 96e42a39b17..3e1e6206478 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -25331,10 +25331,21 @@ struct wglSwapIntervalEXT_params BOOL ret; };
+struct get_pixel_formats_params +{ + TEB *teb; + HDC hdc; + struct wgl_pixel_format *formats; + unsigned int max_formats; + unsigned int num_formats; + unsigned int num_onscreen_formats; +}; + enum unix_funcs { unix_thread_attach, unix_process_detach, + unix_get_pixel_formats, unix_wglCopyContext, unix_wglCreateContext, unix_wglDeleteContext, diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index c02436f1675..c7b0bbfdf34 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -35,6 +35,7 @@
#include "wine/glu.h" #include "wine/debug.h" +#include "wine/wgl_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(opengl); WINE_DECLARE_DEBUG_CHANNEL(fps); @@ -294,6 +295,52 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd) return best_format; }
+static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, + UINT *num_onscreen_formats ) +{ + struct get_pixel_formats_params args = { .teb = NtCurrentTeb(), .hdc = hdc }; + NTSTATUS status; + + if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; + if (!(args.formats = malloc( sizeof(*args.formats) * args.num_formats ))) goto error; + args.max_formats = args.num_formats; + if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; + + *num_formats = args.num_formats; + *num_onscreen_formats = args.num_onscreen_formats; + return args.formats; + +error: + *num_formats = *num_onscreen_formats = 0; + free( args.formats ); + return NULL; +} + +INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDESCRIPTOR *ppfd ) +{ + struct wglDescribePixelFormat_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .ipfd = index, .cjpfd = size, .ppfd = ppfd }; + NTSTATUS status; + struct wgl_pixel_format *formats; + UINT num_formats, num_onscreen_formats; + + TRACE( "hdc %p, index %d, size %u, ppfd %p\n", hdc, index, index, ppfd ); + + if ((formats = get_pixel_formats( hdc, &num_formats, &num_onscreen_formats ))) + { + if (!ppfd) return num_onscreen_formats; + if (size < sizeof(*ppfd)) return 0; + if (index <= 0 || index > num_onscreen_formats) return 0; + + *ppfd = formats[index - 1].pfd; + + free( formats ); + return num_onscreen_formats; + } + + if ((status = UNIX_CALL( wglDescribePixelFormat, &args ))) WARN( "wglDescribePixelFormat returned %#lx\n", status ); + return args.ret; +} + /*********************************************************************** * wglGetPixelFormat (OPENGL32.@) */ diff --git a/include/wine/wgl_driver.h b/include/wine/wgl_driver.h index 93ebe7d7f46..5bf72a7f269 100644 --- a/include/wine/wgl_driver.h +++ b/include/wine/wgl_driver.h @@ -7,11 +7,16 @@ #define WINE_GLAPI #endif
-#define WINE_WGL_DRIVER_VERSION 23 +#define WINE_WGL_DRIVER_VERSION 24
struct wgl_context; struct wgl_pbuffer;
+struct wgl_pixel_format +{ + PIXELFORMATDESCRIPTOR pfd; +}; + struct opengl_funcs { struct @@ -26,6 +31,7 @@ struct opengl_funcs BOOL (WINE_GLAPI *p_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); BOOL (WINE_GLAPI *p_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); BOOL (WINE_GLAPI *p_wglSwapBuffers)( HDC hdc ); + void (WINE_GLAPI *p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); } wgl;
struct